2011-08-28 6 views
17

以下のコードを実行すると(netbeansを使用して)、割り当てられたヒープサイズは鋸歯状に変化します。使用したヒープグラフを鋸歯状に表示するjVisualVMからのキャプチャを添付しています。プログラムは単純な無限ループ印刷です"lol"は標準出力です。なぜ鋸歯状のグラフですか?

class one{ 
    static int i=0; 
    public static void main(String a[]){ 
     while(i<10){ 
      System.out.println("lol"); 
     } 
    } 
} 

enter image description here 誰もが使用ヒープのグラフの形状の背後にある理由を説明できますか?

PS:私はそれは多少のNetBeansに関連していないので、NetBeansのを使用せずに、それを実行してもこれが起こる...

+1

良いと変わっているようです...ええと... 3メガバイトですか?本当にそれは本当ですか? – Owen

+0

他のガベージコレクタアルゴリズムを試して、これについていくつかの洞察を得てください。 http://www.tikalk.com/java/garbage-collection-serial-vs-parallel-vs-concurrent-mark-sweep – skaffman

+3

@ buch11:最も些細なJavaでさえ、巨大な量のゴミを過小評価しないでくださいメソッド/ APIが生成できます。私はJavaを使ってマルチスレッドの科学計算をしてきましたが、面白くなくても大変だと教えてくれるでしょう;)ほとんどのJavaプログラマは* Map *のようなものをうれしく使っています。それがボトルネックでないならば、それには何も問題はないということです。 Javaは、基本的に、ほとんどすべての人が無駄な無駄を生み出し、次のように考える世界です。*「ガベージコレクタが処理します」*。 PhotoshopがJavaで書かれていない理由があります;) – SyntaxT3rr0r

答えて

23

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

Visual VM - Memory snapshot

興味深いビットは数でありますヒープ上に存在するライブオブジェクト。のこぎり模様は、エデンの空間がいっぱいになるときに発生する若者ガベージコレクションサイクルの結果です。プログラムで実行される重い計算アクティビティがないので、JVMはループのいくつかの反復を実行することができ、エデン空間(4MBのサイズ)がいっぱいになります。後続の若者世代の収集サイクルは、ほとんどのゴミを取り除きます。鋸歯状のパターンの挙動がこのようによって説明することができる

Visual VM GC probes

:オブジェクトがまだ使用中でない限りVisualVMのから得られた以下のGCトレースによって示されるように、それは、ほとんど常にエデンスペースの全体であります若い世代のガベージコレクションサイクルを引き起こす、エデン空間を満たす一連のオブジェクト割り当てが急速に連続しています。このプロセスは、基本となるJVMプロセスが別のプロセスによって先取りされず、オブジェクト割り当てを担当するJVM内のメインスレッドも別のスレッドによって先取りされないため、周期的に繰り返されません。

+0

ポイントを得ました!!!ありがとう。 – buch11

+0

あなたは大歓迎です。 Btw、VisualVMとEclipseの間でAltキーを押し続けると、私は完全なのこぎり波を得られませんでした。一方のスクリーンショットは、あなたがいつかVisualVMを実行していたことを示しています。 –

+0

実際に私はスレッドを使って何かをプログラミングしていましたが、突然コードが無限になりました。JVisualVMに行き、実行中のスレッド/待機中のスレッドを確認しました。それはスレッドに関連するものだと思っていましたが、上のコードを実行しようとしましたが、すべてのパズルはそこから始まったばかりです...私のVisualVMはいつも動いていました。 – buch11

1

は、それがから来ることができた場所がたくさんありますし、それが依存可能性が高い実装です。少なくとも以下の出力ストリームの基本的な方法の1つ指定されたバイト配列の割り当ては、(存在するのSystem.out.println下ストリームのスタック内のどこか

  • 可能である(しかし全て単に推測です)それは、NetBeans VMでオーバーヘッドのwrite(バイト[] B、オフint型、int型のlen))

  • それはオーバーヘッドあなたは(私はそれを使用していませんでした使用している監視ソフトウェアで使われています)

  • です出力が終わるところで

5

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

System.outに書き込み中にJavaプロセスが割り当てメモリを保持しているのではないかと疑問に思う場合は、他のスレッド(現在のメモリ統計情報をJVisualVMに送るスレッドなど)がメモリを割り当てるスレッドである可能性があります。

1

実際に追加のオブジェクト割り当てを引き起こすjVisualVM。 jVisualVMとjconsoleはJava Management Extensionsを使用しています。実行中のアプリケーションにアタッチし、JVMメトリックを要求して、その追加のオブジェクトが作成されている。 あなたは、JVMのヒープ内の空きメモリを報告

Runtime.getRuntime().freeMemory() 

にあなたのプログラムの呼び出しに追加することでこれを確認することができます。あなたのコードを実行することによって[ほとんど]メモリの変更は表示されませんが、jVisualVMをプログラムに接続するとすぐにメモリ使用量が増えます。

関連する問題