Java WeakReferenceオブジェクトの作成とガベージ コレクションに関連するランタイム コストを調べた人はいますか? マルチスレッド アプリケーションのパフォーマンスの問題 (競合など) はありますか?
編集:明らかに、実際の回答は JVM に依存しますが、一般的な観察も歓迎します。
編集 2: 誰かがパフォーマンスのベンチマークを実行したことがある場合、またはベンチマークの結果を指摘できる場合、それは理想的です。(申し訳ありませんが、賞金は期限切れです...)
Java WeakReferenceオブジェクトの作成とガベージ コレクションに関連するランタイム コストを調べた人はいますか? マルチスレッド アプリケーションのパフォーマンスの問題 (競合など) はありますか?
編集:明らかに、実際の回答は JVM に依存しますが、一般的な観察も歓迎します。
編集 2: 誰かがパフォーマンスのベンチマークを実行したことがある場合、またはベンチマークの結果を指摘できる場合、それは理想的です。(申し訳ありませんが、賞金は期限切れです...)
WeakReferencesは、CMSガベージコレクターに悪影響を及ぼします。私たちのサーバーの振る舞いからわかる限り、それは並列発言フェーズ時間に影響を与えます。このフェーズでは、すべてのアプリスレッドが停止するため、非常に望ましくありません。したがって、WeakReferencesに注意する必要があります。
私は Java ガベージ コレクターを一度実装したので、私が達成できたものは何でも (弱い :) 可能なことの下限です。
私の実装では、ガベージ コレクション中に弱参照がアクセスされると、弱参照ごとに少量の一定量の追加オーバーヘッドがあります。
つまり、結果は次のとおりです。心配する必要はありません。無数の弱参照を使用していない限り、大きな問題ではありません。
最も重要なことは、コストはヒープ全体のサイズではなく、存在する弱参照の数に比例することです。
ただし、弱参照をサポートするガベージ コレクターが、そうでないガベージ コレクターと同じくらい高速であるとは言えません。ここで想定される質問は、Java が弱参照をサポートしているとすると、弱参照を使用するための増分コストはいくらかということです。
私のものは、単純な「世界を止める」マーク/スイープガベージコレクターでした。ガベージ コレクション中に、すべてのオブジェクトが生きているかどうかを判断LIVE
し、オブジェクト ヘッダーにビットを設定します。次に、すべての非ライブ オブジェクトを通過して解放します。
弱い参照を処理するには、次を追加するだけです。
LIVE
ます (つまり、LIVE
参照されるオブジェクトのビットが設定されることはありません)。LIVE
であり、それWeakReference
が である場合、そのオブジェクトが弱く参照しているオブジェクトをチェックし、そうでない場合はLIVE
参照をクリアします。このロジックの小さなバリエーションは、ソフト参照とファントム参照で機能します。
あなたが本当に興味があるなら、実装はここにあります。
弱い参照を使用するキャッシュは、ゲッターなどでオンデマンドで再構築する場合、アプリの速度を大幅に低下させる可能性があります。
public Object getSomethingExpensiveToFind() {
if(cache.contains(EXPENSIVE_OBJ_KEY)) {
return cache.get(EXPENSIVE_OBJ_KEY);
}
Object sth = obtainSomethingExpensiveToFind(); // computationally expensive
cache.put(EXPENSIVE_OBJ_KEY, sth);
return sth;
}
このシナリオを想像してください:
1) アプリのメモリが不足しています
2) GC は弱い参照を消去するため、キャッシュも消去されます
3) アプリは続行し、getSomethingExpensiveToFind() などの多くのメソッドが呼び出され、キャッシュが再構築されます
4) アプリのメモリが再び不足している
5) GC は磨耗参照を消去し、キャッシュをクリアします
6) アプリは続行し、getSomethingExpensiveToFind() などの多くのメソッドが呼び出され、キャッシュが再構築されます
7) など...
私はそのような問題に遭遇しました.GCによってアプリが頻繁に中断され、キャッシュのポイント全体が完全に無効になりました。
つまり、不適切な管理を行うと、弱い参照によってアプリケーションの速度が低下する可能性があります。