3

私は、長い時間がかかり、時折 OOM (Java ではなく C ヒープ) を示していた Java 機能テストのプロファイリングを行っていましたが、Java シリアル GC で本当に次善の動作を見つけました (そして、おそらくすべての Java GC に適用されます)。

テスト実行からの完全な GC ポイントでの Permgen 統計のサンプルを次に示します (サイズは KB)。

before  after   commit
167935  167935  167936
172031  172031  172032

ご覧のとおり、permgen スペースはこれらの完全な gc の実行によってクリーンアップされていません。大したことではありませんが、これらの完全な GC が役に立たないことを示しています。さらに、commit 値は少しおかしいです。gc ログ エントリのコミット値は、コミット サイズが増加した後の値になると想定しました。これは実際には、完全な GC 実行前のコミット値だと思います。

さらに、permgen コミット サイズは、完全な GC 実行ごとに 4MB (172032K ~ 167936K) の固定された調整不可能なサイズで大きくなると思います。つまり、たとえば 64 MB のデフォルトの permgen サイズで開始し、アプリケーションが完全に起動したときに 128 MB の permgen が必要な場合、permgen が最終的なコミット サイズに達するまでに 16 個のフル gc が必要になります。

私がプロファイリングしていた機能テストの場合、58 個のフル GC を実行する必要があり、それぞれに 0.5 ~ 2 秒かかりました。jvm 引数 -XX:PermSize を -XX:MaxPermSize に等しくすることで、完全な GC をゼロに減らすことができました (はるかに高速な新世代の GC を大幅に増やすことなく)、GC インストルメンテーションによって報告される GC 時間を短縮することができました。 90 秒から 9 秒に、メッセージを 90% 削減します。

多くの場所を調べましたが、permgen ヒープのコミット サイズの増加率を調整する別のパラメーターを見つけることができませんでした。プログラムの起動時に permgen ヒープの可能な最大サイズを完全に割り当てるのは、ちょっと見苦しいです。PermSize を MaxPermSize に等しくする代わりに、起動時に大量のメモリを割り当てずに同様の結果を達成できる方法を知っている人はいますか? permgen コミットの増分が非常に小さく固定されているのはなぜですか?

4

1 に答える 1

0

Permgen はガベージ コレクションを行いません。(通常の状況下で)。Permgen は、実際のクラス オブジェクトと Java ランタイムの他の「内臓」が保持される場所です。アプリケーションがさまざまなクラスを初期化して使用したり、jar がロードされたり使用されたりすると、関連するクラス ファイルは基本的に permgen に格納されます。

あなたの観察を説明するアプリに特に関連する他の関連パラメーターが必要でした。

permgen の増加とガベージ コレクションの間には、文書化された関係は実際にはありません。Permgen は、jvm によって使用される静的データを格納するためのものであり、通常は収集されません (ClassLoader がクラスをロードし、その ClassLoader が範囲外になるというまれな状況を除きます)。

于 2012-08-14T21:06:03.560 に答える