2016-11-08 9 views
1
String str = "test"; 

str = str + "test2"; 
str = str + "test3"; 
str = str + "test4"; 
str = str + "test5"; 

上記のコードから作成されるオブジェクトの数と、ガベージコレクションに使用できるオブジェクトの数はどれですか?作成するオブジェクトの数とガベージコレクションに使用できるオブジェクトの数はいくつですか?

誰か説明していただけますか?

+2

http://stackoverflow.com/questions/10443492/how-many-objects-are-createdを参照してください。しかし、その質問は数年前であり、廃止される可能性があります。 – ajb

+0

http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1を参照すると、決定的な回答はないようです。異なる実装では異なる可能性がありますもの。 – ajb

答えて

0

JavaCは、文字列操作に関して非常に奇妙です。たとえば、 "String + = otherString"を実行するときにString.concatを使用しない理由は何ですか?

代わりに、Javaでは、各行の末尾にStringBuilder(またはJavaバージョンに応じてStringBuffer)が作成されます。ストリングを連結していることを確認します。

私はテストプログラム(TCTestWin)でコードを配置して、コマンドラインから呼び出された:あなたは、行ごとに、javacのを見ることができるように

0: ldc   #15     // String test 
    2: astore_1 
    3: new   #17     // class java/lang/StringBuilder 
    6: dup 
    7: aload_1 
    8: invokestatic #19     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    11: invokespecial #25     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    14: ldc   #28     // String test2 
    16: invokevirtual #30     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    19: invokevirtual #34     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    22: astore_1 
    23: new   #17     // class java/lang/StringBuilder 
    26: dup 
    27: aload_1 
    28: invokestatic #19     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    31: invokespecial #25     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    34: ldc   #38     // String test3 
    36: invokevirtual #30     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    39: invokevirtual #34     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    42: astore_1 
    43: new   #17     // class java/lang/StringBuilder 
    46: dup 
    47: aload_1 
    48: invokestatic #19     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    51: invokespecial #25     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    54: ldc   #40     // String test4 
    56: invokevirtual #30     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    59: invokevirtual #34     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    62: astore_1 
    63: new   #17     // class java/lang/StringBuilder 
    66: dup 
    67: aload_1 
    68: invokestatic #19     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
    71: invokespecial #25     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    74: ldc   #42     // String test5 
    76: invokevirtual #30     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
    79: invokevirtual #34     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    82: astore_1 
    83: return 

javap -c TCTestWin.class 

これらは結果ですStringBuilderを作成し、Stringを追加して処理を続行します。

このコードは、特にループ内で使用されると、ガベージコレクタを急いでしまいます。

それを行うための3つのより良い方法があります。

  1. 代わりに使用CONCAT:

    String str = "test"; 
    str = str.concat("test2"); 
    str = str.concat("test3"); 
    str = str.concat("test4"); 
    str = str.concat("test5"); 
    
  2. は、単一のStringBuilderが作成されます連結の単一の行を、使用してください。それぞれを覚えています。別のStringBuilderを作成します。以下の定数ストリングの連結では、Javaコンパイラーが単一のストリングを作成することに注意してください。ただし、1つ以上のString変数を追加すると、StringBuilderが作成されます。

    String str = "test" + "test2" + "test3" + "test4" + "test5"; 
    
  3. のStringBuilderを自分で作成し、連結を行うには、REUSEのStringBuilder。これは、特にループでを実行するときに最高のパフォーマンスを示します

    StringBuilder sb = new StringBuilder(512); 
    for (int i = 0; i < 10000; i++) 
    { 
        sb.setLength(0); 
        sb.append("test"); 
        sb.append("test2"); 
        sb.append("test3"); 
        sb.append("test4"); 
        sb.append("test5"); 
        sb.append(i); 
        String s = sb.toString(); 
    } 
    

したがって、上記のコードから、4つの異なるStringBuildersが作成されます。最後のStringの後に、すべてのStringBuilderが収集されます。

+1

番号付けまたは箇条書きポイントを使用する場合は、次のコードを二重インデントする必要があります。 – EJP

+0

単一の 'StringBuilder'がかなり効率的であるため、複数の' String.concat() '呼び出しを使用しません。プログラマーが考えることができるよりも優れたオブジェクトコードを選ぶコンパイラについては、「非常に奇妙なこと」はありません。それが彼らのためのものです。あなたは実際にその質問に答えていません。 – EJP

+0

完全に同意した場合は、単一のStringBuilderが作成されました。しかし、投稿されたコードは、単一のStringBuilderを作成するのではなく、4つを作成します。 –

0
実行時に

を作成されますどのように多くのオブジェクト

、4、strのすなわち4つの計算値、定数プールから来て初期値を除きます。

ガベージコレクションで使用できるオブジェクトはいくつですか?

このコードの最後ではあるが、strが範囲外になる。3つの中間値はstrです。

私はStringsとカウントしています。各Stringには別のオブジェクトであるchar[]が関連付けられます。

しかし、周囲のコードが、これらのコード行の間でstrが変更できないとJVMが判断できるようなものであれば、それぞれ1と0になる可能性があります。

+0

'String str =" test ";'は、JVMのヒープメモリ内にあるString Constantプール内のオブジェクトも作成します。だからいいえ。オブジェクトの数は5になります。 –

+0

@RohitGaikwadしかし、このコードが実行されると実行時には実行されません。クラスローディング時に発生します。 – EJP

関連する問題