1

JVM Heap Size が Object creation とどのように異なるかを調べようとしています。

たとえば、以下のプログラムが表示されている場合、for ループで 10000 個の文字列オブジェクトを作成していますが、それでも JVM 環境のヒープ サイズに違いはありません。

public class One {

    public static void main(String args[]) {

        long heapSizebefore = Runtime.getRuntime().totalMemory();
        System.out.println("heapSizebefore" + heapSizebefore);

        for (int i = 0; i <= 10000; i++) {
            String str = new String();

        }

        long heapSizeafter = Runtime.getRuntime().totalMemory();
        System.out.println("heapSizeafter" + heapSizeafter);

    }

}
4

4 に答える 4

4

を呼び出すとtotalMemory、Javaプロセスによって予約されているメモリの量がわかります。ヒープ上のオブジェクトでアクティブに埋められているという意味ではありません。javadocsが言うように、これは現在および将来のオブジェクトに使用できるメモリの合計量です。

malloc実際、Javaは、新しいオブジェクトが作成されるたびに呼び出す(または同等のもの)必要があるのではなく、基盤となるオペレーティングシステムから大きなチャンクでメモリを要求することを好みます。

ヒープの実際のサイズを追跡したい場合は、JConsole / JVisualVMなどのツールを使用してリアルタイムで簡単に実行できます。または、メモリプロファイラーを使用してさらに詳細に追跡できます。プログラムで実行する場合は、複雑なもののエージェントを登録する必要がありますが、ヒープの詳細はJMXを介して公開されます。java.lang:MemoryMBeanのHeapMemoryUsage属性(JConsoleがメモリチャートを表示するために使用するもの)を見てください。

于 2012-06-14T15:19:38.480 に答える
2

forJITは、副作用がないため、ループ全体を最適化する可能性もあります。

于 2012-06-14T15:19:51.900 に答える
2

2つの理由:

  1. ライブオブジェクトのサイズの合計ではなく、ヒープ用に予約されているメモリの量を測定しています。
  2. とにかく割り当てられた文字列への参照を保持しないので、JVMは必要なときにいつでも自由にそれらをガベージコレクションできます。
于 2012-06-14T15:20:59.823 に答える
0

基本的に、Java で静的メソッドを使用する理由を知りたかったのです。

静的メソッドはインスタンス メソッドよりも単純だからです。

私の質問は、(オブジェクト作成から)メモリを節約することです。静的メソッドを使用しますか??

いいえ。目的を持ってコーディングし、実際に必要なものだけを作成する必要があります。必要なときにインスタンスを作成し、必要がないときはインスタンスを作成しません。これはパフォーマンス上の理由ではなく、コードの概念的な重みを軽減するためです。自分のコードやその他のコードを保守する必要がある場合は、何かが行われている理由を見つける必要があり、無意味なコードが本当に無意味であると判断するには、かなりの時間がかかります。つまり、存在するものよりも、存在しないものを探す方が時間がかかります。


マルチスレッドのメモリ割り当てをサポートするために、各スレッドにはスレッド ローカル割り当てバッファーまたはTLABがあります。

空き容量は、共通プールの空き容量を示すだけで、各スレッドの TLAB で利用可能なサイズは示しません。十分な文字列を割り当てると、別のブロックが読み込まれるため、メモリ使用量が急激に増加します。

あなたができることは、これをオフにすることです-XX:-UseTLAB

// -XX:+UseTLAB heapUsedBefore: 5,368,848 heapUsedAfter: 5,368,848
// -XX:-UseTLAB heapUsedBefore: 535,048 heapUsedAfter: 535,096

public class One {
    public static void main(String... args) {
        Runtime runtime = Runtime.getRuntime();
        long heapUsedBefore = runtime.totalMemory() - runtime.freeMemory();

        String str = new String();

        long heapUsedAfter = runtime.totalMemory() - runtime.freeMemory();
        System.out.printf("heapUsedBefore: %,d heapUsedAfter: %,d%n", 
                           heapUsedBefore, heapUsedAfter);
    }
}
于 2012-06-14T15:25:13.877 に答える