11

GC のサイクルが長い。私が見たチェックから、ヒープの古い(古い)領域にオブジェクトが多すぎます。どのオブジェクトがヒープのどの領域にあるかを知るためのユーティリティ、またはこれらのオブジェクトに関する静的学はありますか?
Sun/Oracle HotSpot JVM (Java 6) を使用しています。

編集: 私の問題についてもう少し詳しく:
私は大きなヒープ (32GB) を持っており、ヒープの古い領域が 30% しか満たされていない場合でも、GC を手動で実行すると 15 秒の一時停止が発生するように見えます。どのオブジェクトの作成を最適化するかを知るために、どのオブジェクトが古い領域に残っている「生存者」であるかを知りたいです。

4

4 に答える 4

7

現在の世代の JVM で動作するツールやユーティリティを知りません。

しかし、裏を返せば、そのようなユーティリティがどのように役立つかはわかりません。

通常、ヒープがいっぱいになると、長い GC 時間が発生します。ヒープが 100% いっぱいになると、GC で費やされる時間は指数関数的に増加する傾向があります。最悪の場合、ヒープが完全にいっぱいになり、アプリケーションがOutOfMemoryError. 考えられる解決策は 2 つあります。

  • 根本的な原因が (アプリケーションが解決しようとしている問題のサイズに対して) ヒープが小さすぎることである場合は、ヒープ サイズを増やすか、アプリケーションのワーキング セットを減らす方法を探します。つまり、計算中に「ライブ」にする必要があるオブジェクトの数/サイズ。

  • 根本的な原因がメモリ リークである場合は、それを見つけて修正します。

どちらの場合も、メモリ プロファイラーを使用すると、問題の分析に役立ちます。ただし、どのオブジェクトが古い世代にあるかを知る必要はありません。問題の根本原因や問題の解決策には関係ありません。


どのオブジェクトの作成を最適化するかを知るために、どのオブジェクトが古い領域に残っている「生存者」であるかを知りたいです。

これはもう少し理にかなっています。具体的にどの空間に住んでいるかではなく、どのオブジェクトが長命であるかを見つける必要があるようです。jhat一連のヒープスナップショットを比較するために使用することで、それを行うことができます。(もっと良い方法があるかもしれません...)

しかし、私はまだこのアプローチが役立つとは思わない。問題は、完全な GC がすべての到達可能な (ハード、ソフト、ウィーク、ファントム) オブジェクトをトラバースする必要があることです。また、30% がいっぱいの 32Gb ヒープがある場合、マーク/スイープ/再配置するオブジェクトがまだたくさんあります。解決策は、並行コレクターを使用して、アプリケーションのオブジェクト割り当て率に追いつくことができるように調整することである可能性が高いと思います。

System.gc()また、コードから直接 呼び出しているようにも思えます。そうしないでください! を呼び出すSystem.gc()と、(通常) JVM は完全なガベージ コレクションを実行します。それはあなたに一時停止を与えることがほぼ保証されています. コレクターをいつ実行するかを決定するために JVM を残す方がはるかに優れています。

最後に、「オブジェクト作成の最適化」が何を意味するのかが不明です。オブジェクトの作成速度を下げるということですか? それとも、長期間存続する (キャッシュされた?) オブジェクトの保持を管理するために何か他のことを考えていますか?

于 2012-06-12T11:56:13.457 に答える
0

特定の世代のオブジェクトを「探索」できるツールは見たことがありません。

私は Netbeans Profiler に慣れています。あなたが求めていることを実際に行うことはできませんが、何が問題なのかを知ることができるツールを備えています.

プロファイラーでアプリケーションを実行し、 を選択すると、列が表示Memoryされます。各オブジェクトの世代はわかりませんが、の数が表示されます。したがって、数値が 1 より大きい場合は、おそらく Tenured (おそらくサバイバー スペース) にあり、数値が常に大きくなると、メモリ リークが発生します。Live ResultsGenerationsSurviving Generations

于 2012-06-12T12:07:50.580 に答える