String constant pool

There are eight basic data types and strings in the JAVA language. To make them faster and more memory efficient during operation, corresponding constant pools are provided. A constant pool is similar to a cache provided at the JAVA system level. Constant pools for all eight data types are system-coordinated, with the StringTable being a special type. It can be used in two ways:

  • Using double quotes, the String is stored directly in the constant pool, for example: String STR = “Hello World”;
  • Put the String into the constant pool using the String supplied intern() method.

Constant pool position changes

  • Before JDK6, the string constant pool was stored in the persistent generation
  • JDK7 moves the location of the string constant pool to the JAVA heap
    • All strings are stored in the heap, so we only need to resize the heap when tuning

Why adjust?

  • PermSize The default size is small
  • The garbage collection frequency of permanent generation is low

StringTable features

  • Strings with the same contents are not stored in the string constant pool
  • The string constant pool is a fixed-size Hashtable with a default length of 1009. If there are too many strings in the constant pool, it will cause a serious hash collision, which will cause the list to become too long (the zipper method resolves the hash collision), which will lead to a significant performance degradation when calling the intern method
  • use-XX:StringTableSizeYou can set the length of StringTable
  • In JDK6, StringTable length is fixed at1009, so if there are too many strings in the constant pool, the efficiency will decrease very quickly.We can set the length arbitrarily
  • In JDK7, the length of StringTable defaults to60013, starting with JDK8,1009 is the minimum value that can be set

The enigmatic splicing operation

The concatenation of strings has always been an important and difficult point in examining string related knowledge. We do not know whether it is a new object or a constant pool. Firstly, the following conclusions are drawn:

  • Concatenation of constants to constants results in the constant pool, and the principle is compile-time optimization
  • No constant with the same content exists in the constant pool
  • As long as one of them is a variable, the result is in the heap. The splicing principle is StringBuilder
  • If the result of the concatenation calls intern, it actively puts string objects that are not already in the constant pool into the constant pool and returns the object address

To verify the

View the corresponding bytecode file:

LDC: Pushes data from the constant pool onto the operand stack

With the decompilation plugin for IDEA we can see that the concatenation of strings is optimized:

Verify the two

It is not hard to see that the String object in the entire class does not increase when the String is printed the second time, indicating that there is only one String in the constant pool.

Validation of the three

View the corresponding bytecode file:

Str2 concatenation is implemented by generating a StringBuilder for append.How many strings does new String(“a”)+new String(“b”) generate?

Note variables that use final:

View the corresponding bytecode file:

Concatenation of variables with final modifications is still optimized by the compiler

Intern ()

If the current string exists in the constant pool, the current string is returned directly. If the string is not in the constant pool, the string is placed in the constant pool and the object reference is returned. Unfortunately, this is a native method, so we can check out the OpenJdk7 source code to find out.

How many objects are created?

How many objects does the new String(“ab”) create?

The answer is two. However, many students do not know why? How do you prove that? Just look at the bytecode

It is not difficult to see that two objects are created, one is the object out of new, and the other is ab(LDC #3) in the constant pool.

Extension: New String(“a”)+new String(“b”)?

From bytecode alone, you can see that five objects were created:

  • new StringBuilder();
  • new String(“a”);
  • “A” in the constant pool;
  • new String(“b”);
  • “B” in the constant pool;

Note the toString method on StringBuilder:

Naive you might say I know, there are two other objects:

  • new String(“ab”);
  • “Ab” in the constant pool;

Look at the bytecode of the toString method:

Note: the toString call does not generate “ab” in the constant pool.

JDK6 has VS JDK7?

What is the result of the following code in JDK6 and JDK7?

  • In JDK6: false false
  • In JDK7: false true

Interpretation of the start

The corresponding memory is shown in the following figure:

expand

By simply switching s3.Intern () and S4, the answer is already false.

Interpretation of the start

The corresponding memory is shown in the following figure:

Intern summary

  • In JDK1.6, try to put this string object into the string constant pool
    • If there is one in the constant pool, it will not be put in, return the existing object address
    • If not, it makes a copy of the object (deep copy), puts it in the constant pool, and returns the object’s address
  • Since JDK1.7, try to put this string object into the string constant pool
    • If there is one in the constant pool, it will not be put in, return the existing object address
    • If not, a copy of the object’s reference address is made, placed in the constant pool, and the object’s address is returned

Intern problem sets

What are the results of running the above two problems in different JDK versions?

Will these two problems differ in the same JDK version?

Welcome to comment!