public class CodeBlock02
{
{
System.out.println("第一代码块");
}
public CodeBlock02()
{
System.out.println("构造方法");
}
{
System.out.println("第二构造块");
}
public static void main(String[] args)
{
new CodeBlock02();
new CodeBlock02();
new CodeBlock02();
}
}
在这里, new CodeBlock02()
; 或者换成 CodeBlock02 code = new CodeBlock02();
他们是一样的吗!
まず、いくつかの概念を明確にしましょう。Java コードは jvm で実行され、jvm のメモリ領域はいくつかのモジュールに分割されます。
プログラム カウンター レジスタ: プログラム カウンターは、現在のスレッドによって実行されたバイトコードの行を示すために使用される比較的小さなメモリ領域です。これは、現在のスレッドの行番号インジケーターとして理解できます。バイトコード インタプリタが動作しているときは、このカウンタの値を変更することによってステートメント命令をフェッチします。
スレッドの各メソッドが実行されると、スタック フレーム (Statck フレーム) が作成され、ローカル変数テーブル、オペレーション ステーション、ダイナミック リンク、メソッド Exit などが格納されます。 . メソッドが呼び出されると、スタック フレームが JVM スタックにプッシュされ、メソッドの実行が完了すると、スタック フレームがスタックからポップアウトされます。
ネイティブ メソッド スタックは、機能、動作メカニズム、例外タイプなどの点で仮想マシン スタックと同じです。唯一の違いは、仮想マシン スタックは Java メソッドを実行するのに対し、ネイティブ メソッドはスタックは、ネイティブ メソッドの実行に使用されます。多くの仮想マシン (Sun の JDK デフォルト HotSpot 仮想マシンなど) では、ネイティブ メソッド スタックと仮想マシン スタックが一緒に使用されます。
ヒープ領域は、Java GCメカニズムを理解する上で最も重要な領域です。ヒープ領域は、JVM によって管理される最大のメモリ領域であり、Java GC メカニズムによって管理されるメイン メモリ領域でもあり、仮想マシンの起動時に作成されます。ヒープ領域は、オブジェクト インスタンスを格納するために存在します。原則として、すべてのオブジェクトはヒープ領域にメモリが割り当てられます (ただし、最新のテクノロジーでは、これはそれほど絶対的なものではなく、一部のオブジェクトはスタックに直接割り当てられます)。
(永続世代とも呼ばれます)、メソッド領域は各スレッドによって共有される領域であり、仮想マシンによってロードされたクラス情報 (つまり、必要な情報) を格納するために使用されます。クラスのロード時にロードされます(バージョン、フィールド、メソッド、インターフェイス、その他の情報を含む)、最終定数、静的変数、オンザフライでコンパイラによってコンパイルされたコードなど。
ダイレクトメモリはJVMによって管理されるメモリではありません。たとえば、4Gのメモリがあり、JVMが1Gを占有している場合、残りの3Gはダイレクトメモリであると理解できます。 JDKにはチャネルとバッファに基づいたメモリ割り当て方式があり、C言語で実装されたネイティブ関数ライブラリはダイレクトメモリに割り当てられ、JVMヒープに格納されたDirectByteBufferによって参照されます。ダイレクトメモリは本機のメモリによって制限されるため、OutOfMemoryError例外が発生する場合もあります。
心配しないで、まず Java で参照がどのように実装されるかを分析しましょう:
Java 参照アクセスには、JVM スタック、ヒープ、メソッド領域の 3 つのメモリ領域が関係します。
最も単純なローカル変数参照: Object obj = new Object() を例として挙げます:
Object obj は、JVM スタックのローカル変数テーブルに格納され、参照型データを表すローカル参照を表します。
オブジェクトクラスの型情報(インターフェース、メソッド、フィールド、オブジェクトタイプなど)のアドレスもヒープに記録され、そのアドレスで実行されたデータはメソッド領域に格納されます。
これを見れば分かるはずです。クラス自身の情報、クラスのインスタンスデータ、オブジェクトを指す参照情報はそれぞれjavaのメソッド領域、スタック領域、ヒープ領域に配置されます。
リーリー
code は、ローカル変数テーブルに格納されている参照であり、ヒープ内のオブジェクト インスタンス データを指します。このオブジェクト インスタンス データは
を通じて取得されます。質問の例:
リーリー
要約すると、コードは new によって生成されたインスタンスを受け取るために使用する「リモート コントロール」であり、ヒープ領域内のこのオブジェクトの特定の場所を指します。Javaの引用符
を理解する必要がありますCodeBlock02 コード = 新しい CodeBlock02();
左側のものは、CodeBlock02 型の 変数 と呼ばれます。
右側のものは、CodeBlock02 タイプの オブジェクト と呼ばれます。
この変数が同じタイプの 2 つの異なるオブジェクトを順番に指すようにすることもできます。
リーリーこのタイプの変数がこのタイプのサブクラスのオブジェクトを指すようにすることもできます:
リーリー次のように、new によって作成されたオブジェクトでメソッドを直接呼び出すこともできます:
リーリーどちらも宣言オブジェクトです。投稿者が求めているのは割り当てであるはずです。
後でこの値を操作し続けない場合、割り当てても割り当てなくても同じになりますCodeBlock02 code = new CodeBlock02(); // 宣言されたオブジェクトを変数に代入し、後続の操作を実行できます
左側がオブジェクトの参照変数、右側が実際にメモリに割り当てられたオブジェクトです。