23

NetBeans を使用して以下のコードを実行すると、割り当てられたヒープ サイズのグラフが鋸歯状になります。ヒープ割り当てグラフを鋸歯状で示す JVisualVM のスクリーン キャプチャを添付します。プログラムは、「Hello, World!」を出力する単純な無限ループです。コンソールに。

public class HelloWorld {
    public static void main(String a[]){
        while(true) {
            System.out.println("Hello, World!");
        }
    }
}

ここに画像の説明を入力 使用済みヒープのグラフの形状の背後にある理由を説明できる人はいますか?

PS : これは、NetBeans を使用せずに実行しても発生するため、NetBeans とは関係ない可能性が高いです...

4

4 に答える 4

28

ヒープの使用における鋸歯状のパターンは、呼び出しの呼び出し中にいくつかのローカル変数が作成されるという事実によって説明できSystem.out.printlnます。HeapCharBufferVisualVM のメモリ プロファイラーを使用して取得した次のスナップショットに示されているように、Oracle/Sun JRE で最も顕著なのは、いくつかのインスタンスが若い世代で作成されることです。

ビジュアル VM - メモリ スナップショット

興味深いのは、ヒープ上に存在するライブ オブジェクトの数です。鋸歯状のパターンは、eden スペースがいっぱいになったときに発生する若い世代のガベージ コレクション サイクルに起因します。プログラムで実行される重い計算アクティビティがないため、JVM はループの複数の反復を実行でき、その結果、eden スペース (サイズは 4MB) がいっぱいになります。後続の若い世代のコレクション サイクルでは、ほとんどのガベージが消去されます。VisualVM から取得した次の gc トレースで示されているように、オブジェクトがまだ使用されていない限り、ほとんどの場合、eden スペース全体です。

ビジュアル VM GC プローブ

したがって、ノコギリ波パターンの動作は、一連のオブジェクト割り当てが立て続けに行われ、eden スペースがいっぱいになり、若い世代のガベージ コレクション サイクルがトリガーされることによって説明できます。基礎となる JVM プロセスが別のプロセスによってプリエンプトされることはなく、オブジェクトの割り当てを担当する JVM 内のメイン スレッドも別のスレッドによってプリエンプトされることはないため、このプロセスは遅延なく周期的に繰り返されます。

于 2011-08-28T23:19:12.340 に答える
7

通常の速度でオブジェクトを割り当てるプロセスでは、ヒープ メモリの消費量が着実に増加し、その後、ガベージ コレクタが使用されなくなったオブジェクトを収集するときに瞬間的に低下し、鋸歯状になります。

java プロセスが への書き込み中に割り当てメモリを保持する理由System.outが気になる場合は、他のスレッド (たとえば、現在のメモリ統計を JVisualVM に供給するスレッド) がメモリを割り当てている可能性があることに注意してください。

于 2011-08-28T11:39:09.730 に答える
1

それが発生する可能性のある場所はたくさんあり、実装に依存している可能性があります。少なくとも次の可能性があります (ただし、すべて単なる憶測です)。

  • System.out.println の下のストリームのスタックのどこかに、バイト配列の割り当てがあります (出力ストリームの基本的なメソッドの 1 つが write(bytes []b, int off, int len) であると仮定すると)。

  • 使用している監視ソフトウェアによって使用されるオーバーヘッドです(私は使用していません)

  • 出力を表示する netbeans VM のオーバーヘッドです。

于 2011-08-28T07:23:26.647 に答える
1

実際にはjVisualVMが追加のオブジェクト割り当てを引き起こしています。jVisualVM と jconsole は Java Management Extensions を使用しています。実行中のアプリケーションにアタッチし、JVM メトリックを要求すると、追加のオブジェクトが作成されます。プログラム呼び出しに追加することで、これを確認できます。

Runtime.getRuntime().freeMemory() 

JVMヒープの空きメモリを報告します。コードを実行しても [ほとんど] メモリの変化は見られませんが、jVisualVM をプログラムに接続するとすぐに、メモリ使用量が増加することがわかります。

于 2012-09-12T23:37:37.423 に答える