2

ClassLoaderは永久世代メモリに保存されます。また、Java HotSpot™ 仮想マシンでのJava メモリ管理のホワイト ペーパーで指定されているように、永久世代メモリは確実にガベージ コレクションされます。それで、カスタムClassloaderはまだメモリリークにつながりますか? はいの場合、なぜそれが起こるのですか?

アップデート

@Marko Topolnik と @Prunge の助けを借りて、私の疑問は明確になりました。また、ClassLoader とメモリ リークについては、次の点が指摘されています。

  1. CustomClassLoaderは Perm 世代に保存されません。
  2. Customが範囲外のClassLoader場合、メモリ リークが発生する可能性がありますが、オブジェクトClassLoderを に設定しても、カスタムがロードしたクラスは引き続きアプリケーションによって参照されます。ClassLoadernull
  3. 特定のオブジェクトが必要ない場合はClassLoader、ロードされたクラスから開発されたオブジェクトへのすべての参照が であることを確認する必要がありますnull
  4. によってロードされたクラスのいずれかがClassLoader適格でないGC場合、ClassLoader は適格ではありませんGCed
4

2 に答える 2

3

カスタム クラスローダ自体がメモリ リークを引き起こすことはありません。それらがロードするクラスが正しく使用されていないと、リークが発生する可能性があります。

クラスとクラスローダは通常どおりガベージ コレクションできます。これはコマンド ライン オプションでオフにでき-Xnoclassgcますが、ユーザーは明示的にこれを行う必要があります。クラスローダはすべてのクラスを参照しているため、クラスローダはすべてのクラスが参照されなくなった場合にのみガベージ コレクションを実行できます。

カスタム クラスローダからロードされたクラスまたはこれらのクラスのインスタンスがまだアプリケーションで参照されている場合、リークが発生する可能性があります。

一般的な例は、Tomcat などの Java EE Web コンテナーです。

コンテナー内の各 webapp には独自のクラスローダーがあると仮定しましょう。Web アプリケーションがアンロードされると、コンテナーはアプリケーションを削除し、すべてのクラス (コンパイル済みの JSP を含む) は参照されなくなります。遅かれ早かれ、クラスとクラスローダーはガベージ コレクションによってクリーンアップされます。しかし、webapp はデータベース ドライバを に登録したDriverManagerか、bean イントロスペクション(リフレクションを行う一般的なサード パーティ製ライブラリを介して間接的に行う可能性が非常に高い) を使用して、bean メタデータをキャッシュに保持し、webapp クラスローダからのクラスが webapp が削除された後も存続している可能性があります。アンデプロイされ、Web アプリケーションのクラスローダーによってロードされていない他のオブジェクトから引き続き強く参照されています。

Tomcat には、考えられるいくつかのリーク シナリオとその回避方法について説明したページがあります。

ただし、カスタム クラスローダーが正しく記述されていれば、リークは発生しません。

于 2013-07-27T14:33:46.637 に答える
2

クラスローダは PermGen 空間に保存されません。クラス データはそこに格納されます。これは、ロードを行ったクラスローダーに間接的にのみ関連します。クラスローダーは、ロードした各クラスへの参照を保持します。

この回答は、1つのことを除いて、良い情報を提供します.PermGenスペースにクラスローダーが割り当てられているのは間違っています. クラスローダーは単純な Java クラスであり、PermGen には通常のオブジェクト データではない特別な素材のみが含まれます。たとえば、すべての静的クラス変数とメソッドの実行可能コードを保持します。

HotSpot のメモリ レイアウトとガベージ コレクションの詳細に関する優れたリソースは、ここにあります。

于 2013-07-27T17:58:53.350 に答える