私はJVM上で動作するアプリケーション(ゲーム)を持っています。java - GCアプリケーションの実行が遅い
ゲームの更新ロジック(60回/秒実行)が終了し、約25%が「タイムスライス」(1/60秒)で使用され、残りの75%がスリープされます。しかし、GCコレクタが稼動すると、75〜200%まで上昇し、実行の残りの部分にとどまります。
ゲームは約70Mbのヒープを使い、約1〜2MB /秒で成長します。 GCを実行すると70Mbに戻りますので、本当のメモリリークはありません。私はこの数字を将来的には下げようとしますが、この範囲では問題ではありません。
ランタイム引数やフラグを持たないJVM 8を使用していますが、私に与えるGCは不明です。
ヒープを異なるサイズに設定しようとしましたが、この現象には影響しません。
私はこれがかもしれ理由として2つの理論があります。
GCは、意図せずに、更新ループ内のキャッシュトラッシングの原因となるように、私のヒープを断片化します。私は、それがループしてそれを更新する際に、データの近接性から大きな利益を受けるロジックを持っています。それは若い(保育園)のいくつかを維持しながら、それは古い領域にいくつかのデータをシャッフルすることができますか?
突然のGC処理がOSを起動させるため、私のメインアップデートトレッドは現在のCPUリソースを必要とせず、優先度が低下することがわかります。 (ただし、現象は、私は、未使用のCPU使用率をオフにスリープ状態にのThread.sleep()をスキップしても解消されない。あなたは、もっともらしい私の理論は。だと思いますか何がそれらについて行うことができ、またはIを何
PS一般的に、update()はGC後75%で終了します。これは、200%のような数値を取得したときにVSyncを使用するときです。
は、キャッシュミスと関連統計を 'perf record'と比較できますか?また、どのJVM?コレクター?どのコマンドラインフラグ? – the8472
ありがとう、私はポストにいくつかの情報を追加しました。 .... – Jake
https://perf.wiki.kernel.org/index.php/Tutorial#Sampling_with_perf_recordを使用していることを意味するかどうかわからないため、GCロギングを有効にして休止時間に関する情報を取得する必要があります(それを行うためのJVMドキュメント) – the8472