15

私は permgen リークのトラブルシューティングを試みており、jmap -permstat からの出力を解釈する方法について意見を求めたいと思っています。

次のような jmap -permstat レポートがあるとします。

class_loader        classes  bytes     parent_loader       alive?  type

<bootstrap>            4791  25941568                null   live  <internal>
0x00000007203ed508        0         0  0x00000007203ed228   dead  com/example/object/SomeObjectType$FirstClassLoader@0x0000000something1
0x000000071dc17620        1      3056  0x0000000705e692a8   dead  sun/reflect/DelegatingClassLoader@0x0000000something4
0x000000071f26a898        0       100                null   dead  com/example/object/SomeClassLoader@0x0000000something3
0x0000000721c6dba0        0       100                null   dead  com/example/object/SomeClassLoader@0x0000000something3
0x000000071e36df20        0       100                null   dead  com/example/object/SomeClassLoader@0x0000000something3
0x000000072157c1b8      339   2069112  0x000000072157b8d8   dead  com/example/object/SomeObjectType$SecondClassLoader@0x0000000something2
0x00000007128b7830        1      1912  0x0000000700056db8   dead  sun/reflect/DelegatingClassLoader@0x0000000something4
0x0000000707634360        1      3088  0x0000000700056db8   dead  sun/reflect/DelegatingClassLoader@0x0000000something4

上記の出力をどのように解釈するかを次に示します。その際に犯した間違いを修正してください。

「タイプ」列の値は一意ではありません。3 回出現するオブジェクトがいくつかあります。ただし、class_loader の値は 3 つすべてで一意です。したがって、それらのそれぞれは個別のオブジェクトであり、permgen スペースを占有します。この例では、それぞれが 100 バイトを占めています。したがって、300 バイトの permgen スペースが、タイプ SomeClassLoader のオブジェクトによって占有されています。

クラスの値がゼロ以外の場合、このオブジェクトは何らかのクラス ローダーである必要があり、これは参照するクラスの数を示します。(注: 実際のファイルでは、これら 3 つのオブジェクトのバイト列にゼロが含まれています。この例では値を追加しました。実際には、クラス列に 0 がある場合、バイト値はゼロ以外の値にすることができます。)

alive 値が「dead」の場合、オブジェクトはガベージ コレクションの準備ができているが、JVM はそうしていないことを意味します。これが当てはまる理由については、別の議論が必要です。

parent_loader 列に値がある場合、これは別のクラス・ローダーによって参照されているオブジェクトであり、そのオブジェクトがガベージ・コレクションされるまでガベージ・コレクションできません。

最後に: 1) レポートに 500 行が表示され、すべて同じタイプがリストされている場合、2) それらに異なる class_loader 値がリストされている場合、3) バイト列の値を合計することができます。 permgen スペースは、そのタイプのオブジェクトによって占有されています。

これは正しいです?ありがとう!

4

1 に答える 1

6

このブログエントリから:

クラスローダーオブジェクトごとに、次の詳細が出力されます。

  1. (class_loader)クラスローダーオブジェクトのアドレス–ユーティリティが実行されたときのスナップショット。
  2. (クラス)ロードされたクラスの数(メソッド(java.lang.ClassLoader.defineClass)を使用してこのローダーによって定義されます)。
  3. (バイト)このクラスローダーによってロードされたすべてのクラスのメタデータによって消費されたおおよそのバイト数。
  4. (parent_loader)親クラスローダーのアドレス(存在する場合)。
  5. (生きていますか?)「生きている」または「死んでいる」表示–ローダーオブジェクトが将来ガベージコレクションされるかどうかを示します。
  6. (type)このクラスローダーのクラス名。

永続的な生成には、プレーンオブジェクトではなく、クラスメタデータが含まれます(PermGenは実際には何の略ですか?を参照してください)。だから、あなたのステートメントを書き直してください:

最後に:1)すべてが同じタイプをリストしているレポートに500行が表示されている場合、2)異なるclass_loader値をリストしている場合、3)バイト列の値を合計できます4)これは正確にどれだけの量を表しますかpermgenスペースは、同じ(SomeClassLoader)クラスのクラスローダーオブジェクトによってロードされるすべてのクラスのメタデータによって占有されています。

Eclipse Memory Analyzerツールによって表示される「保持されたヒープ」は、オブジェクトによって消費されたヒープメモリ(若い+古い)を指します。

永続的な生成はヒープの外にあり(https://stackoverflow.com/a/12058171/33622を参照)、クラスのメタデータを処理します。

于 2013-03-05T15:55:37.550 に答える