5

「リリースされた」とは、クラスローダーへの参照が残っていないことを意味します。

頻繁に再デプロイされる Java EE アプリケーションが permgen スペースを消費するという問題が発生しています。分析の結果、Java EE アプリのシングルトンがアプリケーションの外部のアプリケーション クラスローダー オブジェクトへの参照を渡し (Java EE 規則に違反して)、アプリのアンデプロイ時にそれらをクリアしていないことがわかりました。

シングルトンまたはクラス オブジェクトへの参照が他に残っていないと仮定すると、そのクラスのクラスローダーが解放されたときにシングルトンの finalize() が呼び出されますか? そこの不正なインバウンド参照をクリアしたいと思います。または、クラスローダー自体がガベージコレクションされるまでファイナライズが呼び出されないcatch-22にいますか?したがって、不正な外部参照のために呼び出されることはありませんか?

ここでの主な質問はおそらく次のとおりです。

この場合、クラスローダーがまだガベージコレクションできない場合、クラスオブジェクトはガベージコレクションされますか? これは、クラスローダの動作の仕様に依存するか、実装に依存する可能性があります。

参照 (別の種類! ;-)) は歓迎されますが、必須ではありません。

4

2 に答える 2

4

そのクラスへの静的参照を持つクラスは、クラス ローダーが GC に適格であり、それへの他の参照がない場合、ガベージ コレクションのみに適格です。

クラスまたはインターフェースは、その定義クラス・ローダーがガベージ・コレクターによって回収される可能性がある場合にのみ、アンロードできます。

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

さらに、すべてのクラスにはそのクラスローダーへの参照があります。そのため、クラスローダーは、それによってロードされたクラスへの参照、または収集不可能なオブジェクトからのそれらのクラスのオブジェクトへの参照がある限り、GCing の対象にはなりません。

ファイナライザーは、オブジェクトがガベージ コレクションの対象になった後、実際の G​​C が行われる前に実行されます。

ファイナライザーで GCing を妨げる着信参照を解放するアプローチは機能しません。オブジェクトがガベージ コレクションの対象になるのを妨げるため、そのような参照が存在する限り、ファイナライザーは呼び出されません。たとえば、この参照チェーンを内部から切り離すことはできません。

singleton instance <--- singleton class <--- class loader <--
<-- any class loaded by that class loader  <-- any object of such a class
<-- object loaded by another classloader referencing such an object or class
于 2012-02-28T21:33:56.287 に答える
1

ファイナライザの動作は、クラス ローダーまたは perm gen の使用によって変更されませんが、パフォーマンスの問題は悪化します。オブジェクトは、ファイナライザーが実行されるまで収集できません。そのため (非並行であると仮定し、弱い/ソフト/ファントムを無視して単純化します)、クラス ローダーを含むオブジェクト グラフへのアクティブな参照がないと判断する GC の実行があります。ファイナライザーはファイナライザー キューに追加され、実行されます。次に、GC の後続のパスの後、メモリを回復できます。これには perm gen 領域を含む完全な GC が必要ですが、これは一般的にまれであり、無効にすることができます。

とにかく、(ステートフルな)シングルトンを使用しないでください。

于 2012-02-28T21:23:29.920 に答える