Bytecode bottom analysis String

Posted May 25, 20203 min read



Immutability:Immutability means that if a String object is created and changes are made, then another object is created instead of the original changes.

Before jdk8, internal storage defined a char type array

After jdk9 is a defined byte type array storage, which can save space better.

The string constant pool is stored in the heap space after jdk1.8(including 8).

String constant pool

The bottom of the String pool is HashTable

So the string constant pool is not repeatable

Such as String s = "abc" s2 = "abc". In fact, it refers to the same address in the stack(compilation optimization)

Before jdk1.6, the default value of HashTable is 1009, jdk7 is 60013, and after jdk8, the minimum length is 1009.

parameter settings

\ -XX:StringTableSize = \ *

Short linked list will affect efficiency

Actual combat

Can be compiled to see the byte code, the following are based on jdk1.8 to explain

Statement:1. Create String literally then a space will be added to the string constant pool, but there will be no address in the heap space; method to create String, then will add a space in the string constant pool, and open up a space in the heap, and reference the address of the heap space

Statement:3. Two literals are spliced, then compilation optimization will be carried out during the compilation phase, such as String c = "a" + "b"; during compilation, it will default to String c = "ab", no longer string constant pool Open space separately

Statement:4. Adding String c = new String("a") + new String("b") will not open up new space in the string constant pool, c is just a reference

public void test() {

String s = "javaHeap";

String s1 = "java";

String s2 = "heap";

String s3 = s1 + s2;

/\ * \ *

\ * Because compile time s1 s2 is equivalent to creating an object in the string constant pool, do not know the value, you need to quote the address

\ * When assigning, then the bottom layer will use the StringBuilder append method for stitching, which refers to two addresses and assigns to form a new object, and there is no "a, javaHeap" in the string constant pool

\ * /

boolean result = s == s3; //false


public void test2() {

String s = "javaHeap";

final String s1 = "java";

final String s2 = "heap";

String s3 = s1 + s2;

/\ * \ *

\ * The final value has been determined during the compilation period, and will be compiled and optimized during string concatenation String s3 = "javaHeap"

\ * /

boolean result = s == s3; //true


public static void test3() {

String s = new String("javaHeap");

/\ * \ *

\ * 5 objects are created in memory, 6 in detail

\ * in the heap

\ * 2. "String" in the string constant pool

\ * 3. + Variable stitching Created StringBuilder

\ * Plus:the toString method in StringBuilder, the bottom layer is new String(); but it will not be created in the constant pool

\ * /

String s2 = new String("java") + new String("Heap");


public static void test4() {

/\ * \ *

\ * The difference between literal and new

\ * 1. Literals will be put in the string constant pool, and new objects will also be put in the "javaHeap" in the constant pool

\ * 2. Literals will not open up space in the heap, while new will open up space in the heap

\ * /

String b = new String("javaHeap"); //It returns the address in the heap space

String a = "javaHeap";

System.out.println(a == b); //false


intern method


Intern method:check if there is in the string constant pool, if there is, then return the reference in the string constant pool. Enter the constant pool.

Why use intern?

:Reduce the size of the memory, increase the speed of operation, will automatically release the memory, will refer to the data in the constant pool

Detailed combat

public static void test() {

/\ * \ *

\ * Detailed memory structure:

\ * New String creates objects in the heap and literals in the string constant pool, MT5

\ * Second line:(When creating a literal, first check whether there is an object reference in the heap, if there is, then it will not be created, and the address in the heap is referenced in the string constant pool.)

\ * String s = "javaHeap";

\ * Literal:only constants will be created in the constant pool.

\ *

\ * So when comparing, new is the object reference address in the constant pool, and the literal is the value(or address), so false

\ * /

String s2 = new String("javaHeap");


String s = "javaHeap";

System.out.println(s == s2); //false


public static void test2() {

/\ * \ *

\ * Detailed memory structure:

\ * Here is the structure of the first line of code(6 objects were created, and finally objects s = "javaHeap" were not generated in the variable pool)

\ * Second line:generated in the variable pool

\ * Third line:Direct reference to the variable pool

\ *

\ * /

String s = new String("java") + new String("Heap");


String s2 = "javaHeap";

System.out.println(s == s2); //true


//------------------------------------------------ -------------------------------------------------

public static void main(String \ []args) {

String str2 = new String("xin") + new String("cen");

//String str2 = new String("a");

String intern = str2.intern();

String str = "xincen";

System.out.println(intern == str); //true Compare addresses in the string constant pool

System.out.println(str2 == str); //false compares the addresses in the heap