2016-11-18 8 views
4

私はJVM上で動作するアプリケーション(ゲーム)を持っています。java - GCアプリケーションの実行が遅い

ゲームの更新ロジック(60回/秒実行)が終了し、約25%が「タイムスライス」(1/60秒)で使用され、残りの75%がスリープされます。しかし、GCコレクタが稼動すると、75〜200%まで上昇し、実行の残りの部分にとどまります。

ゲームは約70Mbのヒープを使い、約1〜2MB /秒で成長します。 GCを実行すると70Mbに戻りますので、本当のメモリリークはありません。私はこの数字を将来的には下げようとしますが、この範囲では問題ではありません。

ランタイム引数やフラグを持たないJVM 8を使用していますが、私に与えるGCは不明です。

ヒープを異なるサイズに設定しようとしましたが、この現象には影響しません。

私はこれがかもしれ理由として2つの理論があります。

  1. GCは、意図せずに、更新ループ内のキャッシュトラッシングの原因となるように、私のヒープを断片化します。私は、それがループしてそれを更新する際に、データの近接性から大きな利益を受けるロジックを持っています。それは若い(保育園)のいくつかを維持しながら、それは古い領域にいくつかのデータをシャッフルすることができますか?

  2. 突然のGC処理がOSを起動させるため、私のメインアップデートトレッドは現在のCPUリソースを必要とせず、優先度が低下することがわかります。 (ただし、現象は、私は、未使用のCPU使用率をオフにスリープ状態にのThread.sleep()をスキップしても解消されない。あなたは、もっともらしい私の理論は。だと思いますか何がそれらについて行うことができ、またはIを何

PS一般的に、update()はGC後75%で終了します。これは、200%のような数値を取得したときにVSyncを使用するときです。

+0

は、キャッシュミスと関連統計を 'perf record'と比較できますか?また、どのJVM?コレクター?どのコマンドラインフラグ? – the8472

+0

ありがとう、私はポストにいくつかの情報を追加しました。 .... – Jake

+0

https://perf.wiki.kernel.org/index.php/Tutorial#Sampling_with_perf_recordを使用していることを意味するかどうかわからないため、GCロギングを有効にして休止時間に関する情報を取得する必要があります(それを行うためのJVMドキュメント) – the8472

答えて

0

VALID:

私がテストを行なったし、完全に私のアーキテクチャを台無しにしました。私は、アプリケーションのボトルネックだったこの、持っていた:

class Physics{ 
    Vec2 centre; 
    Rec hitbox; 
    Vec2 speed; 
    Vec2 acc; 
    ... 

    public void update(){ //critical method 
     centre.doThings(); 
     hitbox.doThings(); 
     etc... 
    } 

} 

をそしてだけ利用プリミティブにそれを変更:

class Physics{ 
    double centreX,centreY; 
    double x1,x2,y1,y2; 
    double speedX,speedY; 
    double accX,accY; 
    ... 

    public void update(){ //critical method 
     implementation of methods above... 
     etc... 
    } 

} 

この少なくとも、Javaはクラスプリミティブメンバーはに格納されることを保証し、以来、ヒープ上のクラスヘッダの下に宣言された順序。オブジェクトへの参照は、ヒープの反対側のアドレスになる可能性があります。

これは、コンパクトGCと一緒に、私はキャッシュヒットの増加に驚きました。それは私の建築を破壊しましたが、それは私が支払うことになる価格です。

ゲームは安定した15%で実行されるようになりました。今では自分の投稿を回答としてマークします。

編集: これはちょうど混乱した男の話題でした。上記はアプリケーションのバグが原因で、アーキテクチャの変更が正当化されなかったため残りの部分はパフォーマンスが大幅に向上しました。コンパクト化のGCは少し助けてくれました。

0

あなたはどう思いますか私の理論は妥当であるか

第1の理論は考えられるが、第2の理論はそうではない。

はそれらについて

何かを行うことができますあなたはおそらくによって物事を向上させることができます:最大ヒープサイズを大きく

  1. 低休止コレクタに切り替える。
  2. パフォーマンスの最適化アプリケーションのプロファイリングの結果に基づいて
  3. ごみの発生率を低減しようとしています。

またはCまたはC++に切り替える必要がありますか?

CとC++は、オブジェクトを動かすものがないため、より予測可能な動作をします。適切なスキルを持って努力すれば、特にグラフィック/レンダリングを行うときにはCおよびC++でより良いパフォーマンスを得ることができます。しかし、それは大きな "if"です。

もはや
+0

Thanks Steven、1。ヒープサイズを増やしてみましたが、役に立たないです。確かに、それはGCの最初の到着を延期するが、その効果は同じままである。 – Jake

+0

2.私は入り込み、GCについて深く掘り下げなければならないと恐れていました。 – Jake

+0

3.私はあなたの意味を確信していません – Jake

関連する問題