8

JMX を介して JVisualVM でリモートアプリケーションを表示すると、アイドル時のメモリ使用量が鋸歯状に表示されます。

ここに画像の説明を入力

ヒープ ダンプを取得して JVisualVM で分析すると、メモリの大きなチャンクが参照のないいくつかの大きなint[]配列にあることがわかります。ヒープ ダンプを比較すると、これらがメモリを取得し、定期的にGC。

私自身のコードが故意にint[]配列を割り当てないことに興味をそそられたので、これらを追跡することに興味があります。

私は netty のような多くのライブラリを使用しているため、犯人は他の場所にある可能性があります。フレームワークがほぼ同じ組み合わせの他のサーバーがありますが、この鋸歯状のものは見当たりません。

誰がそれらを割り当てているかを知るにはどうすればよいですか?

4

2 に答える 2

3

ヒープダンプを取り、それらを保持しているオブジェクトを見つけます。どのオブジェクトが配列を保持しているかがわかれば、何がそれらを割り当てているかを簡単に理解できるはずです。

あなたの質問には答えませんが、私の質問は次のとおりです。

なんで気にするの?

jvm ガベージ コレクター (GC) に、最大 1 GB のメモリを使用できることを伝えました。Java は 250M 未満を使用しています。

GC は、いつガベージ コレクションを行うか、およびガベージ コレクションでどれだけハードに動作するかについて賢くしようとします。グラフでは、メモリの需要はありません。jvm は、設定した 1 GB の制限に近くありません。GC が非常に懸命に努力する必要がある理由はまったくわかりません。なぜあなたも気にするのかわかりません。

ガベージ コレクターが怠惰であることは良いことです。GC の動作が少ないほど、アプリケーションで使用できるリソースが増えます。

JVisualVM の [GC を実行] ボタンを使用して GC をトリガーしようとしましたか? そのボタンは、「世界を止める」ガベージ コレクション操作をトリガーする必要があります。グラフがこれらの鋸歯状の上昇の中間にあるときに試してみてください。もしそうなら、それはメモリのこぎり歯が単なるガベージの蓄積であり、GC が正しいことをしていることを証明しています。

これは、私が使用する Java swing アプリケーションのメモリ使用量のスクリーンショットです。 ここに画像の説明を入力

鋸歯状のパターンに注目してください。

あなたは int[] が心配だと言いました。メモリ プロファイラを起動してすべてをプロファイリングすると、int[] の割り当てが表示されます。

ここに画像の説明を入力

基本的に、すべての割り当ては ObjectOutputStream$HandleTable.growEntries メソッドから行われます。割り当てが行われたスレッドが、ネットワーク メッセージを処理するためにスピンアップしたようです。
jmx自体が原因だと思います。おそらくrmiによるものです(rmiを使用していますか?)。またはデバッガー (デバッガーが接続されていますか?)。

于 2013-06-17T20:57:09.903 に答える
1

int[]この質問に、のこぎり歯のパターンは非常に正常であり、配列とは必ずしも関係がないことを追加したいと思いました。これは、新しい割り当てが Eden-gen で発生し、エフェメラル コレクションがいっぱいになるとトリガーされ、古い gen がそのままになるために発生します。したがって、プログラムが何らかの割り当てを行っている限り、Eden gen は繰り返しいっぱいになり、空になります。特に、単位時間あたりの割り当て量が一定の場合、非常に規則的な鋸歯状のパターンが見られます。

Hotspot の GC がどのように機能するかを詳しく説明している記事がウェブ上にたくさんあるので、ここで詳しく説明する必要はありません。エフェメラル コレクションがどのように機能するのかまったくわからない場合は、このテーマに関するウィキペディアの記事を参照してください (「ジェネレーション GC」セクションを参照してください。このコンテキストでは、「ジェネラル」と「エフェメラル」は同義語です)。

ただし、int[]配列に関しては、少し謎です。私はそれらも見ています.SOについては、本当の答えのない別の質問があります。参照のないオブジェクトがヒープ ダンプに表示されるのは、実際には正常ではありません。通常、ヒープ ダンプにはライブ オブジェクトしか含まれていないためです (Hotspot は、実際にヒープをダンプする前に常に stop-the-world コレクションを実行するため)。私の個人的な推測では、それらはある種の内部 JVM データ構造の一部として割り当てられている (したがって、Java ヒープからではなく、Hotspot の C++ 部分からの参照のみを持っている) と思われますが、それは純粋な推測にすぎません。

于 2013-12-18T06:32:15.053 に答える