1

JConsole で確認された次のコードは、ヒープ サイズが一定して増加していることを示しています。ヒープが最大 25 MB に達すると、GC が実行され、ヒープ サイズがほぼ 3 MB に減少します。これは予想される動作ですか? とても驚きました!

public class Dummy {
    public static void main(String[] args) {
        System.out.println("start");
        while(true){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Snow Leopard を使用しています。

4

5 に答える 5

8

jconsole との通信により、オブジェクトが割り当てられます。ここに表示されているのは、測定方法のアーティファクトだと思います。コードをコンパイルするときに、HotSpot によってわずかに割り当てられることもあります。心配な場合は、プロファイラーを使用して何が割り当てられているかを確認してください (ここでも、プロファイラーのインターフェイスによる割り当てに注意してください)。

通常の GC の動作は、不必要な実行を避けることです。Web のいたるところにメモリ使用量の鋸歯状グラフが表示されます。ここでは、キャッシュとスワップの使いやすさと作業の回避との間に妥協点があります。また、サーバー HotSpot は、クライアント HotSpot よりも積極的にメモリを使い果たします。

于 2010-01-18T21:34:46.777 に答える
4

はい、これは予想される動作です。オブジェクトの割り当てに固有のことは何もしていませんが、sleep の実装が行われている可能性があります。そうでない場合でも、JVM で他のスレッドが実行されている可能性があります。

于 2010-01-18T21:29:37.933 に答える
3

はい、正常です。オブジェクトを明示的に作成しているわけではありませんが、実装の一部として一時オブジェクトを作成する可能性があるメソッドを呼び出しています。それらの一時的なオブジェクトは、GC を実行してそれらを一掃する時が来るまで山積みになります。

于 2010-01-18T21:22:31.797 に答える
2

クラスファイルはそのように見え、コードは 8 から 14 までループし、java.lang.Thread.sleep() はネイティブです。したがって、MB のオブジェクトを作成する理由はありません。

 public static void main(java.lang.String[] args);
     0  getstatic java.lang.System.out : java.io.PrintStream [16]
     3  ldc <String "start"> [22]
     5  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]
     8  ldc2_w <Long 5000> [30]
    11  invokestatic java.lang.Thread.sleep(long) : void [32]
    14  goto 8
    17  astore_1 [e]
    18  aload_1 [e]
    19  invokevirtual java.lang.InterruptedException.printStackTrace() : void [38]
    22  goto 8

残念ながら、JProfiler 自体 (ダミー テスト アプリにどのようにアタッチしたかはわかりません) またはこの vm で実行されている他のものからのものです。JProfiler がこの情報を表示しない場合、どのオブジェクトが作成されたかを調べるには、ヒープ ダンプを実行する必要があります。

'

于 2010-01-18T21:35:35.937 に答える
1

その原因には明らかに 2 つの説があり、経験的な推論に基づいて区別することはできません。簡単な実験を提案できますか。

  1. プログラムを 5000 ミリ秒ではなく 1 ミリ秒スリープするように変更します。まあ違うだろう...)

  2. 現在のアプローチを使用してプログラムを実行します。たとえば、jconsole を使用します。

  3. jconsole などを使用せずにプログラムを実行しますが、"-verbose:gc" オプションを指定して、GC がいつ実行されるかを確認できるようにします。

最後のケースで GC が実行されるのを待っていると、忍耐力が尽きてしまうのではないかと思います...sleepできるだけ速く呼び出しても。

于 2010-01-19T00:16:16.377 に答える