6

多くのクラスを含む大規模なGUIアプリをScalaで作成しており、すべてのクラスをロードできるようにするには、PermGenスペースを増やす必要がありました。アプリ自体は一連の画面ベースのアクティビティを表示し、各アクティビティは独自の大きなクラスのセットをロードします。どの時点でも、1つのアクティビティのみがロード/表示されます。いくつかの活動を経た後、私たちはOutOfMemoryErrorPermGenスペースにいました。

PermGenスペースはヒープの他の部分と同じようにガベージコレクションさClassLoaderれることを理解していますが、クラスのアンロードを可能にするために、たとえばアクティビティごとに1つ持つことで、必要なPermGenスペースを減らすことができるかどうかを確認したいと思います。

それで:

  1. システムClassLoaderによってロードされたクラスは、クラスローダーによって永久に参照されるため、アンロードできないことを理解しています。本当?
  2. カスタムクラスローダーによってロードされたクラスのインスタンスがもう存在せず、クラスローダーをガベージコレクションできる場合、そのクラスはアンロードされ、PermGenスペースが解放されますか?
  3. クラスのアンロードに関する警告(またはそれを妨げる一般的な間違い)はありますか?
4

1 に答える 1

6

...たとえば、クラスのアンロードを可能にするために、アクティビティごとに 1 つの ClassLoader を使用することで、必要な PermGen スペースを削減できる場合。

はい、クラスをアンロードできる唯一の方法は、使用されているクラスローダーがガベージ コレクションされている場合です。これは、すべての単一クラスへの参照とクラスローダー自体への参照がゼロである必要があることを意味します。

PermGen はどのくらいの大きさですか? 次のように PermGen をバンプするだけで済む場合があります。

-XX:MaxPermGen=256m

コマンドラインで。512mに設定することも珍しくありません。本当に堅牢なソリューションが必要な場合は、「アクティビティ」ごとにカスタム クラス ローダーを使用する必要があります。デバッグを容易にするために、次の自明な引数もコマンド ラインに追加します。

-XX:+TraceClassLoading

これにより、JVM にロードされたクラスがコマンド ラインに出力されます。

于 2011-10-14T17:00:52.463 に答える