Deep understanding of JVM -- memory structure

Deep understanding of JVM (2) -- memory structure (2)

4. Pile

definition

Objects created with the new keyword are placed in heap memory

characteristic

  • The safety of all threads in the heap needs to be considered
  • There is a garbage collection mechanism

Heap memory overflow

java.lang.OutofMemoryError : java heap space. Heap memory overflow

Heap memory diagnostics

jps

jmap

jconsole

jvirsalvm

5. Method area

structure

out of memory

  • Before 1.8, it will cause permanent generation memory overflow
  • After 1.8, it will cause meta space memory overflow

Constant pool

Composition of binary bytecode: basic information of class, constant pool, method definition of class (including virtual machine instructions)

Decompile to view class information

  • Get the of the corresponding class Class file

    • Run cmd in the bin directory corresponding to JDK, or enter it on the IDEA console

    • Enter the absolute path of the corresponding javac class

      F:\JAVA\JDK8.0\bin>javac F:\Thread_study\src\com\nyima\JVM\day01\Main.java
      

      After input, the class will appear in the corresponding directory Class file

  • Enter the absolute path of the javap -v class in the console

    javap -v F:\Thread_study\src\com\nyima\JVM\day01\Main.class
    
  • Then you can see the information of the decompiled class on the console

    • Basic information of class

    • Constant pool

    • The method of executing compilation in the virtual machine (what is in the box is the content of the actual compilation execution, # number content needs to be found in the constant pool)

Runtime Constant Pool

  • Constant pool
    • It is a table (such as constant pool in the figure above). The virtual machine instruction finds the class name, method name, parameter type and literal information to be executed according to this constant table
  • Runtime Constant Pool
    • Constant pool is * In the class file, when the class is loaded, its constant pool information will be put into the runtime constant pool, and the symbolic address in it will be changed into the real address

Relationship between constant pool and string pool

String pool StringTable

features

  • Strings in the constant pool are only symbols and will not be converted to objects until they are used
  • The string pool mechanism is used to avoid repeated creation of string objects
  • The principle of string variable splicing is StringBuilder
  • The principle of string constant splicing is compiler optimization
  • You can use the intern method to actively put string objects that are not in the string pool into the string pool
  • Note: both strings in the string pool and in the heap are objects

Used to put string objects, and the elements in them are not repeated

public class StringTableStudy {
	public static void main(String[] args) {
		String a = "a"; 
		String b = "b";
		String ab = "ab";
	}
}

The information in the constant pool will be loaded into the runtime constant pool, but this is a b ab, which is only the symbol in the constant pool and has not become a java string

0: ldc           #2                  // String a
2: astore_1
3: ldc           #3                  // String b
5: astore_2
6: ldc           #4                  // String ab
8: astore_3
9: return

When ldc #2 is executed, the symbol a will be changed into a "a" string object and put into the string pool (hashtable structure cannot be expanded)

When ldc #3 is executed, the symbol b will be changed into a "b" string object and put into the string pool

When ldc #4 is executed, the symbol AB will be changed into an "ab" string object and put into the string pool

Final StringTable ["a", "b", "ab"]

Note: the creation of string objects is lazy. The string will be created and put into the string pool only when it runs to that line of string and does not exist in the string pool (such as ldc #2).

The process of creating a string using a concatenated string variable object

public class StringTableStudy {
	public static void main(String[] args) {
		String a = "a";
		String b = "b";
		String ab = "ab";
		//Splice string objects to create new strings
		String ab2 = a+b; 
	}
}

Decompiled results

	 Code:
      stack=2, locals=5, args_size=1
         0: ldc           #2                  // String a
         2: astore_1
         3: ldc           #3                  // String b
         5: astore_2
         6: ldc           #4                  // String ab
         8: astore_3
         9: new           #5                  // class java/lang/StringBuilder
        12: dup
        13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        16: aload_1
        17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String
;)Ljava/lang/StringBuilder;
        20: aload_2
        21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String
;)Ljava/lang/StringBuilder;
        24: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/Str
ing;
        27: astore        4
        29: return

The process of creating strings by splicing is: stringbuilder() append(“a”). append(“b”). toString()

The return value of the last toString method is a new string, but the value of the string is consistent with the spliced string, but there are two different strings, one in the string pool and the other in the heap memory

String ab = "ab";
String ab2 = a+b;
//The result is false because ab exists in the string pool and ab2 is an object returned by the toString method of StringBuffer and exists in heap memory
System.out.println(ab == ab2);

Creates a string using the method of splicing string constant objects

public class StringTableStudy {
	public static void main(String[] args) {
		String a = "a";
		String b = "b";
		String ab = "ab";
		String ab2 = a+b;
		//Create a string using the method of splicing strings
		String ab3 = "a" + "b";
	}
}

Decompiled results

 	  Code:
      stack=2, locals=6, args_size=1
         0: ldc           #2                  // String a
         2: astore_1
         3: ldc           #3                  // String b
         5: astore_2
         6: ldc           #4                  // String ab
         8: astore_3
         9: new           #5                  // class java/lang/StringBuilder
        12: dup
        13: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        16: aload_1
        17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String
;)Ljava/lang/StringBuilder;
        20: aload_2
        21: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String
;)Ljava/lang/StringBuilder;
        24: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/Str
ing;
        27: astore        4
        //ab3 gets strings directly from the string pool during initialization
        29: ldc           #4                  // String ab
        31: astore        5
        33: return
  • When using the method of splicing string constants to create a new string, because the content is a constant, javac will be optimized during compilation. The result has been determined as AB during compilation, and "ab" has been put into the string pool when creating AB, so ab3 directly obtains the value from the string pool, so the operation is the same as ab = "ab".
  • When you use the method of splicing string variables to create a new string, because the content is a variable, its value can only be determined at run time, so you need to use StringBuilder to create it
intern method 1.8

Calling the intern method of the string object will try to put the string object into the string pool

  • If the string object does not exist in the string pool, it is put successfully
  • If there is this string object, it fails to be put in

The string object in the string pool will be returned no matter whether the insertion is successful or not

Note: if the intern method is called successfully at this time, the heap memory and the string object in the string pool are the same object; If it fails, it is not the same object

Example 1

public class Main {
	public static void main(String[] args) {
		//"A" and "B" are put into the string pool, and str exists in heap memory
		String str = new String("a") + new String("b");
		//Call the intern method of str. if there is no "ab" in the string pool, the string object will be put into the string pool. At this time, the heap memory and "ab" in the string pool are the same object
		String st2 = str.intern();
		//Assign a value to str3, because there is "ab" in the string pool at this time, the contents in the string pool will be returned directly
		String str3 = "ab";
		//Because the heap memory and "ab" in the string pool are the same object, the following two statements Print true
		System.out.println(str == st2);
		System.out.println(str == str3);
	}
}

Example 2

public class Main {
	public static void main(String[] args) {
        //The string object "ab" is created here. Because there is no "ab" in the string pool, it is put into the string pool
		String str3 = "ab";
        //"A" and "B" are put into the string pool, and str exists in heap memory
		String str = new String("a") + new String("b");
        //At this time, because "ab" already exists in the string pool when creating str3, putting in fails, but "ab" in the string pool will be returned
		String str2 = str.intern();
        //false
		System.out.println(str == str2);
        //false
		System.out.println(str == str3);
        //true
		System.out.println(str2 == str3);
	}
}
intern method 1.6

Calling the intern method of the string object will try to put the string object into the string pool

  • If there is no string object in the string pool, a copy of the string object will be copied and put into the string pool
  • If there is this string object, it fails to be put in

The string object in the string pool will be returned no matter whether the insertion is successful or not

Note: at this time, the string object in the string pool and the string object in the heap memory are not the same object regardless of whether the intern method is called successfully or not

StringTable garbage collection

When the memory of StringTable is tight, garbage collection will occur

StringTable tuning

  • Because StringTable is implemented by HashTable, the number of HashTable buckets can be appropriately increased to reduce the time required for strings to be put into the string pool

    -XX:StringTableSize=xxxx
    
  • Consider whether you need to pool string objects

    You can use the intern method to reduce repeated pooling

Keywords: Java jvm intellij-idea

Added by Haberdasher on Fri, 11 Feb 2022 19:20:54 +0200