4

反復ごとに40ミリ秒のタイムキャップを持つタイムクリティカルなアプリケーションに取り組んでいます。タイムキャップを1回だけ超えると、アプリケーションは終了し、ゲームオーバーになります。アプリケーション自体は40ミリ秒のマークを下回っていても問題はありません。制限を超えるのは、ガベージコレクターである場合があります。

ファクトリパターンと組み合わせたオブジェクトプールを使用して、ガベージコレクションの必要性をほとんどなくすことができ、アプリケーションは、アプリケーションが1つの完全なGCを開始した後の10〜20回の反復を除いて、小さなGCの実行を含む安定した17ミリ秒の反復時間を達成します。 40ミリ秒を超えて発生し、アプリケーションを強制終了します。

私の質問は、この1つの完全なGCの原因を正確に分析するにはどうすればよいですか?jvisualvmを集中的に使用して、ランタイムとメモリフットプリントのプロファイルを作成しました。これは、キャッシュする必要のあるオブジェクトを特定するのに非常に役立ちました。しかし、この特定のケースでは、jvisualvmで適切なボタンを押すことができるずっと前に、完全なGCが発生するため、使用できません。プログラムでヒープダンプを生成する方法はありますか?

4

5 に答える 5

3

YourKit のような市販のメモリ プロファイラを使用します。問題を解決するのに十分な期間、これらのほとんどから無料の評価ライセンスを取得できます。;)

私が VisualVM で見つけた問題は、オブジェクトの作成を最小限に抑えると、最大のメモリ プロデューサーがメモリ プロファイラ自体になるということです。市販のプロファイラーは、オフ ヒープ メモリを使用するため、この問題はありません。

ごみをさらに減らすために何ができるか見てみたいと思います。17 ミリ秒はまだ長い時間です。CPU プロファイリングも検討してください。CPU プロファイラは、約 0.5 ミリ秒まで有効です。それ以下の場合は、独自の正確なタイミングといくつかの試行錯誤を使用する必要があります。

CPU プロファイルとメモリ プロファイルを実行した後、両方を同時に実行すると、改善できる点についてより多くの提案が得られます。

生成するガベージの量を減らして eden スペースを増やすと、マイナー コレクションを 1 日に 1 回しか取得できない可能性があります。

http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

于 2012-09-02T12:24:16.093 に答える
1

jprofilerの評価版を試すことができます。これにより、アプリにプロファイラーの起動を待機させることができます。ヒープメモリには影響せず、一般に強力なプロファイラーであり、優れたIDE統合とワンクリックセットアップを備えています。

ただし、ヒープサイズやgc設定は制御できないと言うので、できることはあまりありません。起動時にクラスをロードすると、収集する必要のあるガベージが作成されます。

私が尋ねるかもしれません:これは宿題ですか、それともある種のコンテスト/チャレンジですか?

于 2012-09-02T12:44:03.457 に答える
1

HeapDumpOnCtrlBreakについて聞いたことがありますか。このリンクを試してください

または代わりに使用する

jmap -dump:format=b,file=<filename.hprof> <pid>
于 2012-09-02T12:14:54.680 に答える
1

JVM でのガベージ コレクションは、ほとんどの場合大きな利点ですが、主な欠点 (ご指摘のとおり) は、予期しない GC の一時停止が発生する場合があることです。

標準の JVM は、ソフト リアルタイム (時折の一時停止を許容できる場合) には問題ありませんが、ハード リアルタイム (つまり、所定の許容範囲を超える一時停止がエラー/失敗を引き起こす場合) には適していません。

役立つアドバイスは次のとおりです。

  • 可能であれば、専用のリアルタイム JVM に移行します (例: Zing JVM )。これは、Java でリアルタイムの動作を確実に取得するための最良の方法です
  • Javolution などの低遅延ライブラリを使用しますこれらは、データ構造に非常に低いオブジェクト割り当てレートを提供することで大いに役立ちます (したがって、GC オーバーヘッドが少なくなります)。
于 2012-09-02T12:28:28.517 に答える
0

ガベージコレクションパラメータを調整してみましたか?十分なRAMと複数のコアを備えたマシンを使用している場合は、並列ガベージコレクションを利用できるはずです。Java1.6JVMではデフォルトで有効になっています。基本的に、オブジェクトが古い世代(シリアルに収集される)に昇格されないように、若い世代が十分に大きいことを確認する場合。

于 2012-09-02T12:45:49.897 に答える