3

アプリケーション、特にそのメモリ フットプリントをよりよく理解したいと考えています。

私はガベージコレクションの概念を理解しており、ヒープには常に一定量の死んだオブジェクトが存在することを認識していますが、JConsole (または JVisualVM) での監視が提供するように、この量を最小限に抑えたいと考えています。現在必要な (占有されていない) スペースに関する情報。

(応答性と実行時間を犠牲にして) ヒープ内の死んだオブジェクトの量を最小限に抑えるように、SunVM 内の既存のガベージ コレクター (G1GC など) を構成する方法はありますか?

明確化

私の目的をより明確にするために:私のアプリケーションは非対話型であるため、時間の経過に伴うメモリフットプリントは2回の実行間でほぼ同じです。最小限必要なヒープ領域と、コードの変更がそのフットプリントに及ぼす影響を判断したいと考えています。JConsole からの出力は、死んだオブジェクトのため、ここではあまり役に立ちません。また、私のピークメモリーが本当にある時点で突出したピークなのか、それとも時間の経過とともに伸びているのかについても知りたいです。これが、OOME に到達するまで Xmx を減らしても、そこにたどり着けない理由です。

また、ここでは本番環境での使用ではなく、開発者テストでの使用について話しています。本番環境では、もちろん、より現実的なメモリ フットプリントよりもスループットとパフォーマンスの方が重要です。

4

4 に答える 4

5

アプリケーションが使用しているメモリの総量を知りたい場合は、かなり長い間監視する必要があります。アプリケーションのランダムな瞬間のヒープのサンプル:

jps -> output the pid of java process
jmap -dump:live,format=b,file=heap.bin [pid]

次にjhat、ヒープをナビゲートします。そうするための別のツールがあります。

これを行うと、現時点でヒープに何があるかがわかります。

などのオブジェクトmemory mapped filesはヒープではなくメモリに格納されることに注意してください。

到達したらOOM、これを追加してから、出力を読み取って、実際にヒープ内にあるオブジェクトを確認してください。

-XX:-HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof

これを行うには、を有効にしてから、GCViewerGC logなどのツールを使用します。

-XX:+PrintGCTimeStamps
 -XX:+PrintGCDetails
-verbose:gc
-Xloggc:garbage_collector -> this set the file of the output

ヒープについて話すとき、私はあなたがtenuredスペースについて話していることを理解しています。もしそうなら、あなたはオブジェクトの平均寿命を知る必要があります。そして、いくつかのベストプラクティスに従って、微調整を行います。また、を発行してSystem.gc()も、が実行されることを保証するものではないことに注意してGCください。

事はインスタンスが行きyoung generation (eden)、それがいっぱいになるminor GCと実行されるということです。まだ到達可能なオブジェクトは、と呼ばれる2つのスペースのいずれかに渡されsurvivorます。これがいっぱいになると、そのスペースはにダンプされtenuredます。いっぱいになると、がfull GC実行され、到達できないすべてのインスタンスが削除されます。

できることの1つはprimitives、メソッドで使用することです。それらの寿命はスレッドスタックにあるため、それらはヒープに配置されません。

有用なパラメータは、のサイズを結び付けるパラメータですtenured and young generation (eden)。これらは比率で機能します。多くを発行する場合はGC、の最大時間を設定することを念頭に置いてGC stopください。

いくつかの興味深いパラメータは次のとおりです。

-XX:MinFreeHeapRatio=  
-XX:MaxHeapFreeRatio=  
-XX:NewRatio=
-XX:SurvivorRatio

たとえば、設定-XX:NewRatio=3とは、若い世代と古い世代の比率が1:3であることを意味します。つまり、エデンとサバイバースペースの合計サイズはヒープの4分の1になります。

とにかく、なぜこの要件が必要なのかわかりません。私は通常、についてのみ心配し、が悪いthroughput場合にのみこれらのパラメーターを気にします。throughput

于 2012-06-28T08:04:58.217 に答える
0

-XgenconfigJavaアプリケーションを起動するときにフラグを渡すことができます。あなたはここでそれについてもっと読むことができます。

ウェブサイトからの引用:

genconfigスイッチを使用して、若い世代と古い世代のヒープサイズを明示的に指定できます。また、旧世代のコレクターを指定することもできます。(genconfigオプションを使用すると、-Xmsおよび-Xmxオプションは不要になりますが、genconfigオプションと一緒に使用した場合でも、旧世代のヒープサイズを制限する手段として-Xmxが使用されます。)

小さいヒープサイズを指定すると、GCがより頻繁にトリガーされます。これがまさにあなたが探しているものだと思います。

于 2012-06-28T08:03:01.283 に答える
0

GCサブシステムをデフォルトよりもアグレッシブに構成する方法は確かにありますが、すべての確率で、コードをゼロガベージに向けてワープしようとしている潮流と戦っていることに気付くでしょう。標準のJavaライブラリは、実質的にすべてのステップで、短命のオブジェクトの高速gcに依存しています。例としては、文字列の連結、forループの拡張、オートボクシングなどの単純なものがあります。

于 2012-06-28T08:03:40.580 に答える
0

はい、可能ですが、アプリケーションの動作によって異なります。この答えは、GC ログを実験して有効にすることによってのみ見つけることができます。

これを使用して、アプリの古い世代の最小サイズを見つけることができ、その後、若い世代のさまざまなサイズの実験を開始できます。

  • 若い世代が小さいほど、コレクションの頻度は高くなりますが、メモリ フットプリントは小さくなります。
  • 世代が大きいほど、コレクションの頻度は低くなりますが、メモリ フットプリントが大きくなります

若い世代が小さすぎる場合、オブジェクトが古い世代で早期に昇格する可能性があることに注意してください。これは、より多くの完全な GC コレクションが表示されるときに検出できます。

于 2012-06-28T08:18:52.633 に答える