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, input
jconsole
4. jvisualvm
- enter
jvisualvm
Method area
structure
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
-
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
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