静的メソッドと静的変数はJavaのどこに保存されますか?


115

例えば:

class A {
    static int i=0;
    static int j;

   static void method() {
       // static k=0; can't use static for local variables only final is permitted
       // static int L;
    }
}

これらの変数は、Java、ヒープ、スタックメモリのどこに格納されますか?それらはどのように保存されますか?


2
Oracleの公式ウェブサイト上でガベージコレクションを理解するために非常に有用なリンク:oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/...
Arnavジョシ

回答:


144

静的メソッド(実際にはすべてのメソッド)と静的変数はPermGen、リフレクションデータ(インスタンス関連ではなくクラス関連のデータ)の一部であるため、ヒープのセクションに格納されます。

明確化のための更新

変数とその技術値(プリミティブまたは参照)のみがPermGenスペースに格納されることに注意してください。

静的変数がオブジェクトへの参照である場合、そのオブジェクト自体はヒープの通常のセクション(若い/古い世代またはサバイバースペース)に格納されます。これらのオブジェクト(クラスなどの内部オブジェクトでない場合)は、PermGenスペースに格納されません

例:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.


ガベージコレクションに関する一言:

行う ではないに依存していますfinalize()実行が保証されて。オブジェクトがガベージコレクションの対象である場合でも、ガベージコレクターをいつ実行し、何を収集するかは、JVMが決定します。

もちろん、静的変数をnullに設定して、ヒープ上のオブジェクトへの参照を削除することもできますが、これはガベージコレクターを意味するものではありません それ収集する(参照がなくなった場合でも)。

さらに finalize()は1回だけ実行されるため、例外がスローされないようにするか、オブジェクトが収集されないようにする必要があります。なんらかの例外によってファイナライズを中止した場合finalize()、同じオブジェクトで2回目に呼び出されることはありません。

最後の注記:コード、ランタイムデータなどがどのように格納されるかは、使用されるJVMによって異なります。つまり、HotSpotはJRockitとは異なる方法で実行し、同じJVMのバージョン間でも異なる場合があります。上記はHotSpot for Java 5と6(基本的には同じ)に基づいています。回答した時点では、ほとんどの人がこれらのJVMを使用していると思います。Java 8でのメモリモデルの大きな変更により、上記のステートメントはJava 8 HotSpotには当てはまらない可能性があります。Java7 HotSpotの変更を確認しなかったので、そのバージョンでも上記は当てはまると思います。しかし、ここではわかりません。


1
ああ、あなたは静的変数について確信していますか?AFAIK PermGenは、実際の値ではなく定義のみを保存します。
Amir Raminfar

2
@Amir私は変数自体がpermgenスペースに格納されていることを確信しています。参照されるオブジェクトはおそらくヒープに割り当てられます。これにより、いくつかの情報が追加される場合があります
Thomas

1
はい、変数の定義はpermgenに保存されます。しかし、その価値はヒープ内にあります。あなたの答えは、値がPermGenにも格納されることを示唆しています。
Amir Raminfar

1
@マシュー私の答えをどうやって理解しますか?変数は、それらが参照するオブジェクトではなく、permgenセクション(プリミティブ/参照)に格納されると述べました。変数値の表示方法によって異なります
Thomas

1
@Navは、ヒープのすべての部分がデフォルトでガベージコレクションされるわけではなく、クラスが時々クラスであるため、クラスローダーがまだ参照しているため、静的変数を収集できません。さらに、ガベージコレクターはJVMに完全に依存しているため、ガベージコレクターの実行に依存するべきではありません(実行するタイミングと何を収集するかを決定します。「今すぐgcを実行してください」などのヒントしか提供できません:))。 。
トーマス

25

クラス変数(静的変数)はClass object、そのクラスに関連付けられたものの一部として格納されます。このClassオブジェクトは、JVMによってのみ作成でき、次の場所に格納されますpermanent generationます。

また、一部は呼ばれる非ヒープ領域に格納されていると答えています Method Area.この回答も誤りではありません。ペルムゲンエリアがヒープの一部であるかどうかは、議論の余地のあるトピックです。明らかに、認識は人によって異なります。私の意見では、JVM引数ではヒープスペースとpermgenスペースを別々に提供しています。したがって、それらを異なる方法で処理することをお勧めします。

それを見る別の方法

メモリプールは、実行時にJVMメモリマネージャによって作成されます。メモリー・プールは、ヒープ・メモリーまたは非ヒープ・メモリーのいずれかに属している可能性があります。ランタイム定数プールは、クラス・ファイル内のconstant_poolテーブルのクラスごとまたはインターフェースごとのランタイム表現です。各ランタイム定数プールはJava仮想マシンのメソッド領域から割り当てられ、静的変数はこのメソッド領域に格納されます。また、この非ヒープはperm gen領域にすぎません。実際には、メソッド領域はperm genの一部です。(参照

ここに画像の説明を入力してください


メソッド領域はメモリのPermGenセクションのサブセットではありませんか?メソッド領域(PermGenとメソッド(クラス)領域)がJVMのより大きなヒープ領域の一部であると思うのに、なぜ非ヒープメモリの一部としてメソッド領域を表示したのですか?
Kaveesh Kanwal、2015

最後の行を読むAlso this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur

1
@AniketThakurあなたは非ヒープメモリの一部としてメソッド領域を示しましたが、オラクルのドキュメントによると、ここでは、docs.oracle.com / javase / specs / jvms / se7 / html /…、メソッド領域は論理的にヒープ。
Karan

21

Java 8より前:

静的変数は、permgenスペース(メソッド領域とも呼ばれます)に格納されました。

PermGenスペースはメソッド領域とも呼ばれます

PermGen Spaceは3つの物を保管するために使用されていました

  1. クラスレベルのデータ(メタデータ)
  2. インターンされた文字列
  3. 静的変数

Java 8以降

静的変数はヒープ自体に格納されます。Java8以降、PermGen Spaceは削除され、以前のPermgen Spaceとは異なり、Heapの一部ではなくなったMetaSpaceという名前の新しいスペースが導入されました。Meta-Spaceはネイティブメモリ(OSが特定のアプリケーションに使用するために特定のアプリケーションに提供するメモリ)に存在し、クラスメタデータのみを格納します。

インターンされた文字列と静的変数は、ヒープ自体に移動されます。

公式情報については、JEP 122:Permanent Gen Spaceを削除してください。


> Java8の静的変数に対して「ヒープ自体」と言ったとき、正確には:OldGen?
Ewoks

15

これは、単純な答えと長続きする答えを持つ質問です。

単純な答えはヒープです。クラスおよびクラスに適用されるすべてのデータ(インスタンスデータではない)は、ヒープの永続的な生成セクションに格納されます。

長い答えはすでにスタックオーバーフローにあります:

あるJVMのメモリとガベージコレクションの完全な説明だけでなく、その話し合い、より簡潔な答えそれについては。


3
確実なこと!それらが有用であるとわかったら、それらの人々に賛成することを忘れないでください。
Vasiliy Sharapov


5

トーマスの答えに加えて、静的変数はメソッド領域と呼ばれる非ヒープ領域に格納されます。


4

静的変数はクラスレベルの変数であるため、「永続的な世代」のヒープメモリを格納します。見てください 、この JVMの詳細については。これが役に立てば幸い


3

静的変数はヒープに格納されます


7
静的変数はメモリ内のPremGenスペースに格納され、それらの値はヒープに格納されます。
Akash5288 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.