web-dev-qa-db-ja.com

静的変数の実際のメモリの場所は何ですか?

静的変数はプログラムの実行期間全体に割り当てられるため、スタックもヒープも便利ではありません。それではどこですか?ロードされる場所があるはずですか?

26
Reuben

静的フィールドは、クラスがロードされると初期化され、そのクラスのクラスローダーがアンロードされると破棄されます。それらはクリーンアップでき、別のクラスローダーで複製することさえできます。

OSGiを使用するようなアプリケーションの場合、アプリケーションの存続期間中静的変数は存続しませんが、何度もリロードできます。

これの実装方法はJVMに依存する場合がありますが、Sun/Oracle JVMはクラスの静的フィールドを保持する「オブジェクト」を作成します。このオブジェクトは、この「オブジェクト」フィールドを調べるためにも使用できるUnsafeクラスを介してアクセスできます。

19
Peter Lawrey

メモリには3つのセグメントがあります。

  1. スタックセグメント—ローカル変数と参照変数(ヒープ内のオブジェクトのアドレスを保持する変数)が含まれます。

  2. ヒープセグメント—ランタイムで作成されたすべてのオブジェクト、オブジェクトのみに加えてオブジェクト属性(インスタンス変数)が含まれます。

  3. コードセグメント—ロード時に実際のコンパイルされたJavaバイトコードが存在するセグメント。静的メンバー(変数またはメソッド)はクラスメンバーと呼ばれ、クラス(バイトコード)が存在する場所に存在しますコードセグメント。

32
Sourav

静的変数はプログラムの実行期間全体に割り当てられるため、スタックもヒープも便利ではありません。

実際、静的フレーム(静的変数を保持するフレーム)はヒープから割り当てられます。

また、プログラムの実行中に必ずしも存在するわけではありません。たとえば、親クラスローダー、すべてのクラス、およびすべてのインスタンスが到達不能になった場合、動的にロードされるクラスの静的フレームはガベージコレクションできます。

8
Stephen C

JVMが使用する5つのメモリ領域のうち、静的フィールドにはメモリが割り当てられます クラスエリア(PremGenの一部) クラスが準備およびロードフェーズ中にアプリケーションクラスローダーによってロードされたとき。フィールドがプリミティブの場合、値はクラスエリアに格納され、オブジェクトタイプ(new演算子が使用される)の場合、ヒープに格納されますが、参照はクラスエリアの割り当てられた静的フィールド変数に与えられます。クラスがアンロードされると、その静的フィールドのメモリもGCによるガベージコレクションに利用できます。

フィールドがファイナル、つまり静的ファイナルでもある場合、クラス領域の下の定数プールに保持されます。

1
hi.nitish

http://www.daniweb.com/software-development/Java/threads/34695 から:

静的変数のメモリは、スタック(プログラム専用に確保されたメモリ)ではなく、プログラムの開始時に通常のメモリに割り当てられます。これの利点は、変数またはプロシージャを完全に一定にし、誤って値を変更できないことです。これの欠点は、プログラムが終了するまでメモリが割り当て解除されないことです。静的な値が定期的に宣言されている場合よりも多くのメモリを消費するということは聞いたことがないが、メモリの使用量は常に一定である。

1
Rupok

静的変数は、コードが保存されているのと同じメモリセグメント(つまり、クラスエリア)のメモリに提供されます。メモリのスタックまたはヒープセグメントとは無関係です。プログラムの全期間を通じてアクセス可能です。

0
Atul Verma