How many objects are created

后端 未结 4 1268
栀梦
栀梦 2020-12-02 00:15

I was having a discussion about usage of Strings and StringBuffers in Java. How many objects are created in each of these two examples?

Ex

相关标签:
4条回答
  • 2020-12-02 00:58

    I've used a memory profiler to get the exact counts.

    On my machine, the first example creates 8 objects:

    String s = "a";
    s = s + "b";
    s = s + "c";
    
    • two objects of type String;
    • two objects of type StringBuilder;
    • four objects of type char[].

    On the other hand, the second example:

    StringBuffer sb = new StringBuffer("a");
    sb.append("b");
    sb.append("c");
    

    creates 2 objects:

    • one object of type StringBuilder;
    • one object of type char[].

    This is using JDK 1.6u30.

    P.S. To the make the comparison fair, you probably ought to call sb.toString() at the end of the second example.

    0 讨论(0)
  • 2020-12-02 01:00

    In terms of objects created:

    Example 1 creates 8 objects:

    String s = "a"; // No object created
    s = s + "b"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
    s = s + "c"; // 1 StringBuilder/StringBuffer + 1 String + 2 char[] (1 for SB and 1 for String)
    

    Example 2 creates 2 object:

    StringBuffer sb = new StringBuffer("a"); // 1 StringBuffer + 1 char[] (in SB)
    sb.append("b"); // 0
    sb.append("c"); // 0
    

    To be fair, I did not know that new char[] actually created an Object in Java (but I knew they were created). Thanks to aix for pointing that out.

    0 讨论(0)
  • 2020-12-02 01:06

    You can determine the answer by analyzing the java bytecode (use javap -c). Example 1 creates two StringBuilder objects (see line #4) and two String objects (see line #7), while example 2 creates one StringBuilder object (see line #2).

    Note that you must also take the char[] objects into account (since arrays are objects in Java). String and StringBuilder objects are both implemented using an underlying char[]. Thus, example 1 creates eight objects and example 2 creates two objects.

    Example 1:

    public static void main(java.lang.String[]);
      Code:
       0:   ldc             #2; //String a
       2:   astore_1
       3:   new             #3; //class java/lang/StringBuilder
       6:   dup
       7:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
       10:  aload_1
       11:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       14:  ldc             #6; //String b
       16:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       22:  astore_1
       23:  new             #3; //class java/lang/StringBuilder
       26:  dup
       27:  invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
       30:  aload_1
       31:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       34:  ldc             #8; //String c
       36:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       39:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       42:  astore_1
       43:  return   
    }
    

    Example 2:

    public static void main(java.lang.String[]);
      Code:
       0:   new             #2; //class java/lang/StringBuilder
       3:   dup
       4:   ldc             #3; //String a
       6:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       9:   astore_1
       10:  aload_1
       11:  ldc             #5; //String b
       13:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       16:  pop
       17:  aload_1
       18:  ldc             #7; //String c
       20:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       23:  pop
       24:  return  
    }
    
    0 讨论(0)
  • 2020-12-02 01:06

    The answer is tied to specific implementations of the language (compiler and runtime libraries). Even to the presence of specific optimization options or not. And, of course, version of the implementation (and, implicitly, the JLS it is compliant with). So, it's better to speak in term of minima and maxima. In fact, this exercise gives a better

    For Ex1, the minimum number of objects is 1 (the compiler realizes that there are only constants involved and produces only code for String s= "abc" ; ). The maximum could be just anything, depending on implementation, but a reasonable estimation is 8 (also given in another answer as the number produced by certain configuration).

    For Ex2, the minimum number of objects is 2. The compiler has no way of knowing if we have replaced StringBuilder with a custom version with different semantics, so it will not optimize. The maximum could be around 6, for an extremely memory-conserving StringBuilder implementation that expands a backing char[] array one character at a time, but in most cases it will be 2 too.

    0 讨论(0)
提交回复
热议问题