質問

私は最近、Javaのメモリ割り当てスキームについて多くのことを読んでおり、さまざまな情報源から読んでいるので、多くの疑問がありました。私は自分の概念を収集しました、そして、私はすべてのポイントを調べてそれらについてコメントするように要求します。私はメモリの割り当てがJVM固有であることを知るようになりましたので、私は事前に言わなければなりません、私の質問は太陽に固有であると言います。

  1. クラス(クラスローダーがロードする)は、ヒープの特別なエリアに移動します:永続的な世代
  2. クラスの名前、クラスに関連付けられたオブジェクト配列、JVM(Java/Lang/Objectなど)で使用される内部オブジェクト、最適化情報などのクラスに関連するすべての情報は、永続的な生成エリアに入ります。
  3. すべての静的メンバー変数は、永久生成エリアに再び保持されます。
  4. オブジェクトは別のヒープに移動します:若い世代
  5. クラスごとに各メソッドのコピーは1つだけです。静的または非静的な方法です。そのコピーは永久生成エリアに配置されます。非静的な方法では、すべてのパラメーターとローカル変数がスタックに移動します。そして、その方法の具体的な呼び出しがあるときはいつでも、それに関連付けられた新しいスタックフレームを取得します。静的メソッドのローカル変数がどこに保存されているのかわかりません。彼らは恒久的な世代の山にいますか?または、彼らの参照だけが恒久的な世代エリアに保存され、実際のコピーはどこかにあります(どこ?)
  6. また、メソッドのリターンタイプがどこに保存されるのかわからない。
  7. (若い世代の)オブジェクトが静的メンバー(永久世代)を使用する必要がある場合、それらには、メソッドの返品タイプなどを保存するのに十分なメモリスペースが与えられます。

これをやってくれてありがとう!

役に立ちましたか?

解決

まず、直接の知識からこれらの答えを確認できる人はほとんどいないことは、今では明確になるはずです。最近のホットスポットJVMに取り組んだり、本当に知るために必要な深さまで研究した人はほとんどいません。ここのほとんどの人(私自身を含む)は、他の場所で書かれたもの、または彼らが推測したものに基づいて答えています。通常、ここに書かれているもの、またはさまざまな記事やWebページで書かれているものは、決定的な場合とそうでない可能性のある他のソースに基づいています。多くの場合、それは単純化されていない、不正確、または単に間違っています。

回答の決定的な確認が必要な場合は、openjdk sourcecodeを本当にダウンロードする必要があります...そして あなた自身の研究をしてください ソースコードを読み取り、理解することにより。 SOについて質問すること、またはランダムなWeb記事をトロールすることは、健全な学術研究技術ではありません。

そうは言っても ...

1)クラス(クラスローダーによってロードされる)は、ヒープの特別なエリアに移動します:永久生成。

Afaik、はい。 (アップデート: : 下記参照。)

2)クラスの名前、クラスに関連付けられたオブジェクト配列のようなクラスに関連するすべての情報、JVM(Java/Lang/Objectなど)で使用される内部オブジェクト、最適化情報は永続的な発電エリアに入ります。

多かれ少なかれ、はい。それらのいくつかのことがあなたが何を意味するのかわかりません。 「JVM(Java/Lang/Objectなど)が使用する内部オブジェクト」は、JVM内部クラス記述子を意味すると推測しています。

3)すべての静的メンバー変数は、永久生成エリアに再び保持されます。

変数自体はい。これらの変数(すべてのJava変数と同様)は、プリミティブ値またはオブジェクト参照のいずれかを保持します。ただし、静的メンバー変数はPermgen Heapに割り当てられたフレームにありますが、それらの変数によって参照されるオブジェクト/配列はで割り当てられる場合があります どれか ヒープ。

4)オブジェクトは別のヒープに行く:若い世代

必ずしも。大きなオブジェクト 五月 終身在庫に直接割り当てられます。

5)クラスごとに各メソッドのコピーは1つだけです。静的または非静的な方法です。そのコピーは永久生成エリアに配置されます。

メソッドのコードを参照していると仮定すると、Afaikはい。しかし、もう少し複雑かもしれません。たとえば、そのコードは、JVMの寿命の異なる時期にバイトコードおよび/またはネイティブコード形式に存在する場合があります。

...非静的な方法では、すべてのパラメーターとローカル変数がスタックに移動します。そして、その方法の具体的な呼び出しがあるときはいつでも、それに関連付けられた新しいスタックフレームを取得します。

はい。

...静的メソッドのローカル変数がどこに保存されているのかわかりません。彼らは恒久的な世代の山にいますか?または、彼らの参照だけが恒久的な世代エリアに保存され、実際のコピーはどこかにあります(どこ?)

いいえ。それらは、非静的な方法のローカル変数と同様に、スタックに保存されます。

6)また、メソッドのリターンタイプがどこに保存されるのかわからない。

あなたが意味する場合 価値 (非void)メソッドコールによって返されると、スタックまたはマシンレジスタで返されます。スタックで返される場合、返品タイプに応じて1つか2つの単語が必要です。

7)オブジェクト(若い世代)が静的メンバー(永久世代)を使用するためにNEESが静的部材に参照される場合、それらにはメソッドのリターンタイプを保存するのに十分なメモリスペースが与えられます。 。

それは不正確です(または、少なくとも、あなたは自分自身をはっきりと表現していません)。

何らかの方法が静的メンバー変数にアクセスする場合、それが取得するのはプリミティブ値またはオブジェクトのいずれかです 参照. 。これは、(既存の)ローカル変数またはパラメーターに割り当てられ、(既存の)静的または非静的なメンバーに割り当てられ、以前に割り当てられた配列の(既存の)要素に割り当てられているか、単に使用および廃棄されます。

  • いかなる場合もありません 新着 参照値またはプリミティブ値のいずれかを保持するために、ストレージを割り当てる必要があります。

  • 通常、オブジェクトまたは配列のリファレンスを保存するために必要なメモリの1つの単語は、通常、ハードウェアアーキテクチャに応じて1つまたは2つの単語を占有します。

  • いかなる場合でも、メソッドによって返されるオブジェクト /配列を保持するために、発信者によってスペースを割り当てる必要はありません。 Javaでは、オブジェクトと配列は常に価値のあるセマンティクスを使用して返されます...しかし、返される値はオブジェクトまたは配列の参照です。

アップデート

Java 8の時点で、PermgenスペースはMetaspaceに置き換えられています。詳細については、これらのリソースを参照してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top