Heap and method area

Definition of heap

  • Through the new keyword, heap memory is used to create objects
  • He is shared by threads, and all objects in the heap need to consider thread safety issues
  • Has a garbage collection mechanism

Heap memory overflow (OutOfMemoryError)

  • Unlimited creation of valid objects can overflow heap memory
  • When troubleshooting heap memory overflow, the heap memory can be set smaller for immediate investigation

Diagnosis of heap memory

1. jps tool

  • View which java processes are in the current system

2. jmap tool

  • View the heap memory usage, enter jmap - head 进程id

3. jconsole tool

  • Graphical interface, multi-functional monitoring tool, continuous monitoring, inputjconsole

4. jvisualvm

  • enterjvisualvm

Method area

structure

img

Memory overflow

  • Before 1.8 will cause permanent generation memory overflow
  • After 1.8, the metaspace memory will overflow

Constant pool

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

View class information through decompilation

  • Obtain the .class file of the corresponding class

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

      img

    • Enter the absolute path of the javac corresponding class

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

      After the input is complete, the class .class file will appear in the corresponding directory

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

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

    • Basic information of the class

      img

    • Constant pool

      img

      img

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

      img

Runtime constant pool

  • Constant pool
    • It is a table (such as the constant pool in the figure above), and the virtual machine instructions find the class name, method name, parameter type, and literal information to be executed according to this constant table
  • Runtime constant pool
    • The constant pool is * .class file, when the after class is loaded , it will be constant pool information into the runtime constant pool , and the inside of the symbolic address into a real address

The relationship between constant pool and string pool

String Table

feature

  • The strings in the constant pool are only symbols and will only be converted into objects when they are used
  • Use the string pool mechanism 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 : Whether it is a string in the string pool or in the heap, it is an object

Used to put string objects and the elements inside 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 ab ab is only a symbol in the constant pool and has not yet 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: returnCopy

When the execution reaches ldc #2, the symbol a will be turned into an "a" string object and placed in the string pool (hashtable structure is not expandable)

When the execution reaches ldc #3, the symbol b will be changed to a "b" string object and placed in the string pool

When the execution reaches ldc #4, the symbol ab will be turned into a "ab" string object and placed in the string pool

The final StringTable ["a", "b", "ab"]

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

The process of creating a string using concatenated string variable objects

public class StringTableStudy {
    
    
	public static void main(String[] args) {
    
    
		String a = "a";
		String b = "b";
		String ab = "ab";
		//拼接字符串对象来创建新的字符串
		String ab2 = a+b; 
	}
}

The result after decompilation

	 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 a string 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 the same as the spliced ​​string, but two different strings, one exists in the string pool and the other exists in the heap memory

String ab = "ab";
String ab2 = a+b;
//结果为false,因为ab是存在于串池之中,ab2是由StringBuffer的toString方法所返回的一个对象,存在于堆内存之中
System.out.println(ab == ab2);

Use the method of splicing string constant objects to create a string

public class StringTableStudy {
    
    
	public static void main(String[] args) {
    
    
		String a = "a";
		String b = "b";
		String ab = "ab";
		String ab2 = a+b;
		//使用拼接字符串的方法创建字符串
		String ab3 = "a" + "b";
	}
}

The result after decompilation

 	  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初始化时直接从串池中获取字符串
        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 constant, javac will be optimized at compile time, and the result has been determined as ab at compile time, and it has been put in the string pool when creating ab "Ab", so ab3 obtains the value directly from the string pool, so the operation performed is the same as ab = "ab".
  • When using the method of splicing string variables to create a new string, because the content is a variable, its value can only be determined at runtime, so you need to use StringBuilder to create
intern method 1.8

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

  • If there is no such string object in the string pool, it is successfully placed
  • If there is the string object, it will fail to put

Regardless of whether the placement is successful or not, the string object in the string pool will be returned

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" "b" 被放入串池中,str则存在于堆内存之中
		String str = new String("a") + new String("b");
		//调用str的intern方法,这时串池中没有"ab",则会将该字符串对象放入到串池中,此时堆内存与串池中的"ab"是同一个对象
		String st2 = str.intern();
		//给str3赋值,因为此时串池中已有"ab",则直接将串池中的内容返回
		String str3 = "ab";
		//因为堆内存与串池中的"ab"是同一个对象,所以以下两条语句打印的都为true
		System.out.println(str == st2);
		System.out.println(str == str3);
	}
}

Example 2

public class Main {
    
    
	public static void main(String[] args) {
    
    
        //此处创建字符串对象"ab",因为串池中还没有"ab",所以将其放入串池中
		String str3 = "ab";
        //"a" "b" 被放入串池中,str则存在于堆内存之中
		String str = new String("a") + new String("b");
        //此时因为在创建str3时,"ab"已存在与串池中,所以放入失败,但是会返回串池中的"ab"
		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 such string object in the string pool, a copy of the string object will be made and then put into the string pool
  • If there is the string object, it will fail to put

Regardless of whether the placement is successful or not, the string object in the string pool will be returned

Note : At this time, no matter whether the intern method is called successfully or not, the string object in the string pool and the string object in the heap memory are not the same object

StringTable garbage collection

StringTable garbage collection occurs when memory is tight

StringTable tuning

  • Because StringTable is implemented by HashTable, you can appropriately increase the number of HashTable buckets and adjust the parameters -XX:StringTableSize=1009 和 2305843009213693951之间to reduce the time required for strings to be placed in the string pool. Generally, the default is more than 60,000.

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

    The intern method can be used to reduce repeated entry into the pool

Guess you like

Origin blog.csdn.net/aaaaa1111111199/article/details/113073972