これは、「Java ガベージ コレクタを強制的に実行する方法を教えてください」という別の質問です。私たちのアプリケーションでは、これを行う正当な理由があると信じています。
これは、通常約 5M のライブ オブジェクトを持つサーバー アプリケーションです。5 分ごとに 1 回、約 60 秒かかる分析タスクを実行します。分析の実行中にフル GC がトリガーされると、約 40M のライブ オブジェクトが存在します。余分な 35M オブジェクトは、分析が完了するとガベージになります。サーバーは常に (分析の実行中であっても) 要求に応答し続ける必要があります。
分析が実行されていないときに呼び出された場合、完全な GC は約 1.5 秒かかりますが、分析が実行されている間は約 15 秒かかります。残念ながら、私たちの割り当てパターンは、分析が 20% の時間しか実行されていないにもかかわらず、分析中にフル GC が通常トリガーされるようなものです。(3 回または 4 回の分析実行ごとにフル GC がトリガーされます。)
古い世代の空き容量が特定のしきい値 (5GB) を下回った場合に、分析実行を開始する直前に、非常に軽蔑されている System.gc() を呼び出すコードを追加しました。この利点は非常に大きなものでした。15 秒の一時停止時間ではなく 1.5 秒の一時停止時間が得られ、より多くのゴミを掘り出し物に解放できます。ただし、System.gc() 呼び出しが無視される場合があり、GC が自動的にトリガーされる数分後に 15 秒の一時停止が発生します。
それでは私の質問: ガベージ コレクターを実行するようにもっと強く説得するためにできることはありますか? 1.7.0_09-icedtea を実行し、Parallel GC を使用しています。(a) ガベージ コレクションを手動で強制する信頼できる方法、または (b) よりインテリジェントな自動決定を行うようにコレクターを調整する方法のいずれかが必要です。(b) ワーキング セットがこのように劇的に変化することをコレクターがどのように検出できるかがはっきりしないため、難しいように思えます。
必要に応じて、かなりのハッカーに頼るつもりです。これは私たちにとって深刻な問題です。(代わりに CMS や G1 コンパクターを検討するかもしれませんが、私は CMS のスループットへの影響に懐疑的です。また、G1 は、私たちが使用する大きなバイト配列に対して動作が悪いと評判です。)
補遺: 本番環境では、これまでの経験から、 System.gc()は通常、完全なガベージ コレクションをトリガーします。少なくとも、私たちがそれを呼んでいる状況では。(10 ~ 30 分ごとに 1 回だけ呼び出すだけで、ヒープはある程度ガベージでいっぱいではありません。) ガベージ コレクションをより確実にトリガーできると便利ですが、ほとんどの場合は役に立ちます。