Java memory structure
1. Program Counter Register
- Function: remember the execution address of the next jvm instruction
For example, when executing instruction 0, the program counter will remember 3. When the execution of 0 is completed, the interpreter will take the instruction of 3 from the program counter, and so on.
The instruction is interpreted into machine code through the interpreter, and the machine code is handed over to the CPU for execution - characteristic:
- Thread private: each thread has its own program counter
Example: when two threads are running, the cpu will have a scheduler component to assign them a time slice, and the cpu will assign a time slice to thread 1. In the time slice, if the code of thread 1 is not executed, the state of thread 1 will be temporarily stored and switched to thread 2. When the code of thread 2 is executed to a certain extent, the time slice of thread 2 is used up, Then switch back and continue to execute the remaining code of thread 1 (for example, when the execution reaches 9, switch to thread 2. After the execution of thread 2, switch to thread 1. Because the program counter records the next one, continue to execute from 10).
- Thread private: each thread has its own program counter
- There will be no memory overflow
2. Java Virtual Machine Stacks
-
Definition: the memory required for each thread to run is called virtual machine stack
-
Each stack consists of multiple stack frames, corresponding to the memory occupied by each method call
Each call of methods 1, 2 and 3 corresponds to the occupation of one memory space -
Each thread can only have one active stack frame, corresponding to the method currently executing
-
Problem analysis:
1. Does garbage collection involve stack memory?
Not involved, because stack memory is nothing more than stack frame memory generated by method calls. The stack frame memory will pop up after each method call, that is, it will be recycled automatically, so there is no need for garbage collection to manage the stack memory.
2. Is the larger the stack memory allocation, the better?
Excessive stack memory will reduce the number of runnable threads. The larger the stack memory, the more recursive method calls can be made
3. Is the local variable in the method thread safe?
The local variables in the method will not be shared with other threads, so there is no concurrency problem. This idea is very good and has been called a way to solve the concurrency problem. There is also a loud name called thread closure.
If a local variable in a method does not escape the function of the method, it is thread safe.
If a local variable references an object and escapes the scope of the method, thread safety needs to be considered. -
Stack memory overflow
1. Too many stack frames lead to stack memory overflow (methods are constantly called, such as recursion)
2. The stack frame is too large, resulting in stack memory overflow -
Thread run diagnostics:
Positioning: use top to locate which process occupies too much cpu
ps H -eo pid,tid,%cpu | grep process id (use ps The command further locates which thread caused it cpu (occupied too high) jstack process id Can be based on thread id Find the thread with the problem and further locate the source code line number of the problem code
Case1: excessive CPU usage:
case2: the program runs for a long time without results
3. Local method stack
- Function: when calling some local methods, the java virtual machine needs to provide memory space for these local methods (code written in c/c + +), such as the notify method of Object class
4. Reactor
- Creating objects with the new keyword uses heap memory
- characteristic:
-Thread sharing, thread safety should be considered for all objects in the heap
-There is a garbage collection mechanism - Heap memory overflow
-Xmx8m public class Demo1_5 { public static void main(String[] args) { int i = 0; try { List<String> list = new ArrayList<String>(); String a = "hello"; while(true){ list.add(a); //hello a = a + a; //hello,hellohello,hellohellohellohello....... i++; } }catch (Throwable e){ e.printStackTrace(); System.out.println(i); } } } java.lang.OutOfMemoryError at java.lang.AbstractStringBuilder.hugeCapacity(AbstractStringBuilder.java:161) at java.lang.AbstractStringBuilder.newCapacity(AbstractStringBuilder.java:155) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448) at java.lang.StringBuilder.append(StringBuilder.java:136) at cn.itcast.jvm.Demo1_5.main(Demo1_5.java:14)
-
tips:
-Program counters, virtual machine stacks, and local method stacks are all thread private
-The heap and method area are public to threads -
Heap memory diagnostics
1.jps tools
Check which java processes are in the current system
2.jmap tool
View heap memory usage jmap - heap process id
3.jconsole tools
Terminal input: jps jmap -heap process id jconsole jvisualvm
Graphical interface, multi-functional monitoring tool, which can monitor continuously
5. Method area
- definition:
The Java virtual machine specification clearly states: "although all method areas logically belong to a part of the heap, some simple implementations may not choose to garbage collect or compress." However, for the hotspot JVM, there is another alias for the method area called non heap, which is to be separated from the heap.
Therefore, the method area is regarded as a memory space independent of the Java heap.
The method area mainly stores classes, while the heap mainly stores instantiated objects - Like Java heap, Method Area is a memory area shared by all threads.
- The method area is created when the JVM starts, and its actual physical memory space can be discontinuous like the Java heap area.
- The size of the method area is the same as the heap space. You can choose a fixed size or extensible.
- The size of the method area determines how many classes the system can save. If the system defines too many classes, resulting in overflow of the method area, the virtual machine will also throw a memory overflow error: Ava Lang. outofmemoryerror: PermGen space or Java lang.OutOfMemoryError:Metaspace
- Load a large number of third-party jar packages
- Too many projects deployed by Tomcat (30 ~ 50)
- A large number of dynamically generated reflection classes
- Closing the JVM frees up memory in this area.
In jdk7 and before, it was customary to call the method area permanent generation. Starting with jdk8, the use of meta space replaced the permanent generation. In essence, method area and permanent generation are not equivalent. Only for hotspot. - internal structure
-
Method area memory overflow:
Memory overflow may occur in the meta space. The dynamic agent dynamically generates class bytecode during operation to complete dynamic class loading. For example, spring and mybatis generate a large number of classes during operation, which may lead to memory overflow in the meta space -
Constant pool and runtime constant pool:
-
The method area contains a runtime constant pool. The bytecode file contains a constant pool.
-
java is generated after compilation Class file is the resource warehouse of class file. An effective bytecode file contains not only the version information, fields, methods, interfaces and other description information of the class, but also one item of information, that is, constant pool table, including various literal quantities and symbolic references to types, fields and methods.
-
Constant pool: it can be regarded as a table. The virtual machine instruction finds the class name, method name, parameter type, literal and other types to be executed according to this constant table.
Quantity value
String value
Class reference
Field reference
Method reference -
Runtime constant pool: runtime constant pool. The 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
For example: #1 will become the real address -
The JVM maintains a constant pool for each loaded type (class or interface). Like array items, data items in the pool are accessed through indexes.
-
The runtime constant pool contains many different constants, including numeric literal quantities that have been specified at compile time, and method or field references that can only be obtained after parsing at run time. At this time, it is no longer the symbolic address in the constant pool, but the real address here. Another important feature of runtime constant pool compared with Class file constant pool is that it is dynamic. It is also possible to add new constants (such as String.intern method) during the runtime constant pool. When creating the runtime constant pool of a Class or interface, if the memory space required to construct the runtime constant pool exceeds the maximum value provided by the method area, the JVM will throw OutOfMemoryError exception
String table: -
The string in the constant pool is only a symbol and becomes an object when it is used for the first time
-
The string pool mechanism is used to avoid repeated creation of string objects
-
The principle of string variable splicing is StringBuilder (1.8)
-
The principle of string constant splicing is compile time optimization
-
You can use the intern method to actively put string objects that are not in the string pool into the string pool
-
1.8 try to put this string object into the string pool. If there is one, it will not be put in. If there is no one, it will be put into the string pool and the string will be
-
Objects in the pool return
-
1.6 try to put this string object into the string pool. If there is one, it will not be put in. If there is no one, it will be copied,
-
If you put it into the string pool, the objects in the string pool will be returned
String splicing operation -
The splicing result of constants and constants is in the constant pool. The principle is compile time optimization
-
Variables with the same content will not exist in the constant pool
-
As long as one of them is a variable, the result is in the heap. The principle of variable splicing is StringBuilder
-
If the result of splicing calls the intern() method (the intent method will put the object into the string pool), the string object not yet in the constant pool will be actively put into the pool and the object address will be returned
Use of intern() -
intern is a native method that calls the methods of the underlying C
-
The String pool is initially empty and is maintained privately by the String class. When calling the intern method, if the pool already contains a String equal to the String object determined by the equals(object) method, the String in the pool is returned. Otherwise, the String object is added to the pool and a reference to the String object is returned.
-
If it is not a string object declared in double quotation marks, you can use the intern method provided by string: the intern method will query whether the current string exists from the string constant pool. If it does not exist, it will put the current string into the constant pool.
For example:
String myInfo = new string("I love atguigu").intern();
-
That is, if you call string. On any string For the intern method, the class instance to which the returned result points must be exactly the same as the string instance directly in the form of a constant. Therefore, the value of the following expression must be true
("a"+"b"+"c").intern()=="abc" -
Generally speaking, interconnected string is to ensure that there is only one copy of the string in memory, which can save memory space and speed up the execution of string operation tasks. Note that this value will be stored in the string inter pool
When a large number of existing strings are used in the program, especially when there are many repeated strings, using the intern() method can save memory space.
Case study:
new String("a") + new String("b") Several objects will be created /** * new String("ab") How many objects will be created? Look at the bytecode and you can see that there are two objects * * @author: mason * @create: 2022-01-27-11:17 */ public class StringNewTest { public static void main(String[] args) { String str = new String("a") + new String("b"); } } Bytecode file is 0 new #2 <java/lang/StringBuilder> 3 dup 4 invokespecial #3 <java/lang/StringBuilder.<init>> 7 new #4 <java/lang/String> 10 dup 11 ldc #5 <a> 13 invokespecial #6 <java/lang/String.<init>> 16 invokevirtual #7 <java/lang/StringBuilder.append> 19 new #4 <java/lang/String> 22 dup 23 ldc #8 <b> 25 invokespecial #6 <java/lang/String.<init>> 28 invokevirtual #7 <java/lang/StringBuilder.append> 31 invokevirtual #9 <java/lang/StringBuilder.toString> 34 astore_1 35 return We created six objects Object 1: new StringBuilder() Object 2: new String("a") Object 3: of constant pool a Object 4: new String("b") Object 5: of constant pool b Object 6: toString One is created in new String("ab")call toString Method is not generated in the constant pool ab public class Demo1_23 { // ["a", "b","ab"] public static void main(String[] args) { //String x = "ab"; String s = new String("a") + new String("b"); // Heap new string ("a") new string ("B") new string ("ab") // Try to put this string object into the string pool. If there is one, it will not be put in. If there is no one, it will be put into the string pool and the objects in the string pool will be returned // Here is to put ab into the string pool String s2 = s.intern(); System.out.println( s2 == "ab"); true,because intern The returned object is the object put into the string pool System.out.println( s == "ab");true,Because will s This string is put into the string pool // System.out.println( s == x ); } } public class Demo1_23 { // ["ab", "a", "b"] public static void main(String[] args) { String x = "ab";//Put into string pool /** Create StringBuffer, put it into string pool, create a object, put it into string pool, create b object, StringBuffer toString+ New alignment ab in stack */ String s = new String("a") + new String("b"); // Heap new string ("a") new string ("B") new string ("ab") // Try to put this string object into the string pool. If there is one, it will not be put in. If there is no one, it will be put into the string pool and the objects in the string pool will be returned // Here is to put ab into the string pool String s2 = s.intern(); System.out.println( s2 == "ab"); true,because intern The returned object is the object put into the string pool System.out.println( s == "ab");true,Because will s This string is put into the string pool // System.out.println( s2 == x );true. S2 is the object in the string pool //System. out. Println (s = = x) false, s is in the heap. X in the string pool } }
Reference: Mushroom blog http://www.moguit.cn