2012-05-21 2 views
5

私の理解は、PermGen(ある意味では)がクラスコードをメモリに保持していることです。多くの場合、クラスパスを参照する多くのjarファイルがあります。 jarファイルがクラスパスに含まれている場合(Tomcatのlibディレクトリなど)、これらすべてのクラスのすべてのクラスが自動的にPermGenにロードされますか?jarのクラスはいつPermGenに入るのですか

同様の質問では、一度クラスのjarファイルが使用されると、PermGenはそのjarファイル内のすべてのクラス、または使用されているクラスだけをロードします(そして、後で必要に応じて残りのクラスファイルをロードします)?

答えて

4

これは、クラスローダの実装とJVMにある程度依存 - Java Virtual Machine specificationはこれを言う:

この仕様は、ロード、 ため再帰の活動(とし、リンクする際に、実装の柔軟性を可能に) は、Javaプログラミング言語のセマンティクスがあることは、起こり 尊重、[...]

は、例えば、実装は、クラスまたはインタフェース個々を各シンボリック 参照を解決することを選択することができます唯一、 (レイジーまたはレイトレゾリューション)を使用する場合、または クラスが検証されている間(静的な解像度)、すべてを一度に解決する場合のみです。これは、 クラスまたはインターフェイスが初期化された後で、一部の実装で 解決プロセスが継続する可能性があることを意味します。

実際には、ファイルの1つのクラスがロードされているという理由だけで、すべてのファイルを自動的にJARファイルにロードする必要はありません。

0

必要なクラスだけがロードされ、permgen空間に格納されます。

0

JLSは、クラスが最初に必要とされるときに、それよりも早くなくても初期化されることを保証します。しかし、実装はロードとリンクを早期に実行することができます。

+0

実際、この仕様では、プリロードクラスを明示的に許可しています。それが使用される前にクラスをロードしなければならないことはかなり明白です。 –

+0

そして、それらを初期化するのはどうですか? –

+0

それは別の問題です。初期化まで関連するクラスのロードが遅れることがあるとは思いますが、初期化はPermGenの使用には関係しません。 –

2

PermGenは、HotSpotの実装の詳細であり、Oracleは将来、それを取り除きたいと述べています[1]。これはJava(VM)仕様の一部ではありません。ロードされたクラスのみがPermGenになります。明示的にトラフClassLoader#loadClassか暗黙的にリンクしてください。誰かがすべてのクラスを明示的にロードしていない限り、使用されているクラス(およびそれらの依存関係)のみでなければなりません。それらに対して反射を実行する。 Springのようなフレームワークはこれを避け、バイトコードをスキャンします。

良いスタートポイントはVisualVMで、ロードされたクラスをPermGenで観察することができます。

[1] JRockitにはPermGenがありません。最近のHotSpotバージョンでは、文字列internプールはもはやPermGenにありません。

+1

java.lang.Classオブジェクト、クラスの名前とメソッド名に関連付けられたjava.lang.Stringオブジェクト、およびクラスによって参照される静的オブジェクトの一部がPermGenにロードされることには注意してください。あなたのバイトコードがそこにロードされるようなものではありません... –