String string concatenation principle

Because String is a very popular class, jvm be optimized before jdk7 jvm maintain a lot of ways to string constants in the constant pool, the pool jdk constant migration to the heap

The method area is a region JVM runtime memory management, thread is a shared memory area, which is used to type information, constant, constant static storage has been loaded virtual machines.

Use quotes to create a string

  • Alone (note alone) use quotes to create a string of the way, the string is constant, it has been determined at compile time stored in the constant pool.
  • Create a string of quotes, the first thing would be to have a constant pool to find no equal to this constant objects, if not the constant object is created in the constant pool; any direct return this constant reference to the object.

So look at this example:

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);//true

New way to create a string

String a = new String("abc");

new keyword, no doubt in memory allocated on the heap, create an object of the String class. Thus, a reference to this point in the stack is a stack of the String object.

Then, because the "abc" is a constant, so constant pool will go to find, there is no such constant presence, if not allocate a space, put the "abc" constant and space to address the constant object to a String object heap inside; if the constant pool've got this constant, constant objects that you use the constant pool references directly chant, you only need to create a String object heap.

new constructor incoming string constants, will heap create a String object, but the object is not to go to a new character array to store the content (value), and will directly use a string constant object array of characters (value) application,

DETAILED Reference

/**
* Initializes a newly created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* @param  original
*         A {@code String}
*/
public String(String original) {
   this.value = original.value;  //只是把传入对象的value和引用传给新的对象, 两个对象其实是共用同一个数组
   this.hash = original.hash;
}

Can still obtain the value of another object directly because the two objects are objects of the same class; value although the private modifier, but the configuration process by original.value.

img

So has the following results

public static void main(String[] args) {
      String s1 = new String("hello");
      String s2 = "hello";
      String s3 = new String("hello");
      System.out.println(s1 == s2);// false
      System.out.println(s1.equals(s2));// true
      System.out.println(s1 == s3);//false
  }

On the "+" operator

Constant direct sum of:

String s1 = "hello" + "word";
String s2 = "helloword";
System.out,println(s1 == s2);//true

true here is that because the compiler optimization of s1 put directly became String s1 = "helloword"; it is equal to the back

Very direct sum amount

 public static void main(String[] args) {
        String s1 = "a";
        String s2 = "b";
        String s3 = new String("b");
        String s4 = s1 + s3;
        String s5="ab";
        String s6 = s1 + s2;
            String s66= s1 + s2;
        String s7 = "a" + s2;
        String s8 = s1 + "b";
        String s9 = "a" + "b";

        System.out.println(s2 == s3);  //false   
        System.out.println(s4 == s5);   //false   s4 是使用了StringBulider来相加了
        System.out.println(s4 == s6);  //false  s4和s6 两个都是使用了StringBulider来相加了
        System.out.println(s6 == s66);     //false   两个都是使用了StringBulider来相加了
          System.out.println(s5 == s7);    //false   s7是使用了StringBulider来相加了
        System.out.println(s5 == s8);  //false   s8是使用了StringBulider来相加了
        System.out.println(s7 == s8);  //false  两个都是使用了StringBulider来相加了
        System.out.println(s9 == s8);  //false  两个都是使用了StringBulider来相加了
    }

Summary The following is:

  Two or more string constant direct addition, "+" will be optimized in the pre-compile time, corresponding to the two or more automated synthesizer string constants a string constant.

Will compile optimized, compiled bytecode plus removed directly put directly define a constant

 Otherwise the string will be used by adding to the StringBuilder.

The String intern () method.

It is a native of the method, the book describes its function : if the string constant pool already contains a string like this String object, String object representing the string pool is returned; otherwise, this character String object that contains added to the constant pool, and returns the String object.

And referred to in the previous versions of JDK1.6 and, due to the constant pool in the permanent assignment generations, we can -XX: PermSize and -XX: MaxPermSize size restriction method indirectly area limited by the capacity of the constant pool.

Moreover, the method returns a reference to the intern, JDK1.6 and JDK1.7 there is not the same place, to look at the example of books:

public static void main(String[] args) {
    String str1 = new StringBuilder("计算机").append("软件").toString();
    System.out.println(str1.intern() == str1);

    String str2 = new StringBuilder("ja").append("va").toString();
    System.out.println(str2.intern() == str2);
}

In this code JDK1.6, two will be false, running in JDK1.7, you will be a true and a false.

The book says, are reasons for the differences: In JDK1.6, intern () method will copy the instance of the string for the first time encountered the permanent generation, citing instances of the string is returned permanently generations, but by StringBuilder string instances created in the Java heap, it is not necessarily the same references, returns false.

The JDK1.7 the intern () will not be replicated instance, cited only the first occurrence of recording the constant pool instance, therefore intern () string and StringBuilder instance references that create a return to the same. Str2 comparison to return false because the "java" string before executing StringBuilder.toString () has appeared, the string constant pool has its references, does not comply with the principle of "first appearance", and "computer software "this is the first occurrence of the string, so return true.

Differences jdk6 7 and 7 because of the constant pool is moved to the heap, and there are differences in the constant pool for the processing, the string 6 will replicate a copy of the stack to the constant pool,

7 just string object heap references into the constant pool, so the first str1.intern () returns a pointer to the heap is just a reference to the object, so that the first occurrence of false.

The second false 7 is because it already has "Java" objects constant pool, so str2.intern () returns a constant reference point to objects in the pool, str2 is the point to the heap object reference, so false

Description of small stringTable

Just to increase the speed, the constant string constant pool maintains a hashTable. Easy to find constants

Here the first mention about the string constant pool, in fact, in order to improve matching speed, that is, to quickly find out if a string constant pool, Java constant pool in design time, also engage Zhang stringTable, this a bit like our hashTable, according to hashCode string to locate corresponding bucket, then loop through the array to find the string corresponding reference. If you find a string, returns a reference, you will not find the string constant into the constant pool, and save a reference to stringTable inside.

In JDK7,8, by -XX: StringTableSize size parameter StringTable

intern jdk1.6 its previous () method

In JDK6, constant pool in the permanent generation of memory allocation, and permanent generation of Java heap memory is physically separated, the implementation of intern method, if the string constant pool, virtual machine does not exist in the string constant pool copy, and returns a reference; If the string already exists, this constant will return that object reference constant pool. It is necessary to use caution intern ways to avoid excessive string constant pool, resulting in slow performance, even PermGen memory overflow occurs.

Look at a picture to understand :( images from https://blog.csdn.net/soonfly/article/details/70147205)

img

Of course, this constant pool and reactor are physically separated.

Anyway, we should seize the "copy" of the word, it is kept constant pool contents "abc" constant object.

Detailed look at an example of points:

   public static void main(String[] args) {
        String a = new String("haha");
        System.out.println(a.intern() == a);//false
    }

First of all, see "haha", the output is not constant pool, it will leave this constant objects in the constant pool, the bottom by ldc command, "haha" is added to the string constant pool, then add the constants in the stringTable references (references like this is the address of a char array of String objects), and a reference point of the heap is the address of the String object, so it must be different. (And in a stack, a region in the process).

jdk1.7 the intern () method

After JDK 1.7, intern method will still go to the query whether there are constant pool already exists, if there is, it returns a reference constant pool, which is before there is no difference, the difference is that, if no corresponding character in the constant pool string, then the string is not copied to the constant pool, but only a reference to the original string generated in the constant pool. Simply put, is the usual amount of pool to put things changed: the original can not be found in the constant pool, make a copy into the constant pool, sucked into the constant pool reference copy of the address on the heap after 1.7.

Of course, this time, the constant pool is removed from the method area came to the heap.

Look at a map:

(Picture from https://blog.csdn.net/soonfly/article/details/70147205)

img

So look back to the example of our book

public static void main(String[] args) {
    String str1 = new StringBuilder("计算机").append("软件").toString();
    System.out.println(str1.intern() == str1);

    String str2 = new StringBuilder("ja").append("va").toString();
    System.out.println(str2.intern() == str2);

Look at an example:

String str2 = new String("str")+new String("01");
str2.intern();
String str1 = "str01";
System.out.println(str2==str1);//true

For this reason returns true, too, str2, when only a heap of String objects, and then call intern, there is no constant pool "str01" the constant objects, so the constant pool to generate a reference to the string heap object.

And then give time str1 assignment, because it is quoted, so go find constant pool, found the constant object, it returns the constant reference to the object, that is, str2 refers to the address pointed to by the String object heap.

So str1 and str2 point to the same thing, it is true.

jdk7 Although the reference is copied to the constant pool, but does not affect the function of the constant pool, is to reduce the constant pool create a constant increase performance constant pool is referenced or can play a role in reducing constant, because the reference will eventually pointing to the real object.

Reference blog

https://www.cnblogs.com/wangshen31/p/10404353.html

Guess you like

Origin www.cnblogs.com/xiezc/p/11913830.html