2016-03-23 8 views
0

以下の2つのテストメソッドを作成しました。文字列のオブジェクトサイズを測定するJava

private static long usedMem = 0; 
private static long newUsedMem = 0; 

public static long getSize() { 
    System.gc(); 
    usedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 
    String s = "test"; 
    String y = "testabcd"; 

    System.gc(); 
    newUsedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 

    return newUsedMem - usedMem; 
} 

public static long getSize2() { 
    System.gc(); 
    usedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 
    String s = "test"; 
    String y = s+"abcd"; 

    System.gc(); 
    newUsedMem = Runtime.getRuntime().totalMemory() 
      - Runtime.getRuntime().freeMemory(); 

    return newUsedMem - usedMem; 
} 

String xとString yのサイズを測定するので、どちらのメソッドも同じ結果をもたらすはずです。しかし、最初のメソッドは常に0を返す一方、2番目のメソッドは常に56を返します(私は各メソッドをループで10回実行して、System.gc()が動作していることを確認しています)。

もう一つ注目すべきは、第一の方法では、関係なく、文字列sとyが、結果は常に0

ですされてどのくらい誰かが私に違いを説明できませんでしたか?

+0

私はMemoryUtilクラスを使用しようとしたときにテストを思いつき、いくつかの相違を観察しました。 私のクラスは次のとおりです。 'public class Person { String firstName =" Alice "; 文字列lastName = "Bob"; } ' ' Person'オブジェクトのサイズを初期化したが結果が一致していないときに 'Person'オブジェクトのサイズを測定するために、' MemoryUtil'と ''実行時間 'の測定値を使用しました。 –

答えて

2

最初の文字列リテラルは常に存在します(クラス初期化時にクラスローダーによってロードされる)ので、割り当てによってメモリが増えません。

同じ理由で、2番目の割り当てで2番目の割り当てが増えます。メモリは、第2の方法では増加します理由です

+0

私の投稿にコメントした後、 'MemoryUtil'ユーティリティはオブジェクト' Person'のメソッド 'getSize2()'と同様の値を返します。それは正しいのではないということですか?私はhttp://www.javamex.com/classmexer/から「MemoryUtil」を取得しました。 –

+0

これをもっと明確にするには。 コンパイラはこれらの文字列をプログラムに埋め込んだので、プログラムが実行されている間にそれらの文字列を変数に代入してもメモリフットプリントは増加しませんでした – dustinroepsch

+2

@HieuNguyen 'MemoryUtil'が内部的に何をしているのか、お手入れ。文字列リテラルのサイズは、オブジェクトのサイズの一部ではありません。 – EJP

0

文字列の連結の束を実行する場合、Javaコンパイラは黙っ

String a = b + c + d;

を変換String a = new StringBuilder(b).append(c).append(d).toString();

+0

'b、c、d 'が非最終値であるか、iliter以外の値である場合のみ。 – EJP