An overview of the
The memory structure of the Java Virtual Machine is not officially known; the Java Virtual Machine Specification uses the term “runtime data area.” According to the Java Virtual Machine Specification, the memory structure of a Java virtual machine can be divided into two parts: public and private. Public refers to the part shared by all threads, namely the Java heap, method area, and constant pool. Private refers to private data for each thread, including: PC registers, Java virtual machine stacks, and local method stacks.
The public part
In a Java virtual machine, the thread sharing portion includes
The Java heap
The Java heap is an area of the JVM devoted to memory allocation for Java instance objects, where almost all instance objects are allocated. It’s almost because there are special cases where small objects are allocated directly on the stack, a phenomenon we call “stack allocation.” I won’t go into that here, but I’ll do that in a later chapter. Let’s dive into the Java heap.
The Java heap is also divided into two regions: the young generation and the old generation. The young generation is further divided into Eden zone, From Survivor 0 zone, and To Survivor 1 zone. As shown in the figure below.
When an object needs to be allocated, an object is always allocated first in the Eden area of the young generation. When the Eden area runs out of memory, the Java Virtual Machine starts garbage collection. In this case, the memory of the unreferenced objects in Eden will be reclaimed, and some objects with a long lifetime will enter the old age. There is a parameter in the JVM called -xx :MaxTenuringThreshold that sets the number of GCS that are required to advance to the old age, that is, objects of the younger generation will enter the old age at the next GC after they have passed a specified number of GCS.
Here’s a question to consider: Why does the Java heap have such a partition?
According to our experience, there must be objects with long lifetime and objects with short lifetime in virtual machine, which is a universal normal distribution law. If we mix them together, the number of short-lived objects will result in more frequent garbage collection. Garbage collection has to scan all memory, but there are some objects that live so long that scanning them is a waste of time. So to improve garbage collection efficiency, partitioning is a natural choice.
Another question worth thinking about is: why is the default virtual machine configuration, Eden: from: to = 8:1:1?
That’s the result of a lot of statistics from IBM. According to IBM’s object lifetime statistics, they found that 80% of objects are short-lived. So they set the Eden area to 80% of the young generation, which can reduce the waste of memory space and improve the utilization of memory space.
Method area, constant pool
Method Regions and MetaSpace
The method area is a concept in the Java Virtual Machine specification, which is a Java virtual machine specification, while the permanent generation, MetaSpace, is a different implementation of the method area. Distinguish between the two concepts.
A method area is an area where Java class bytecode data is stored. It stores structural information for each class, such as runtime constant pools, field and method data, constructors, and so on. As you can see, constant pools are stored in the method area, but the Java Virtual Machine Specification places constant pools and method areas at the same level.
The method area is represented in different versions of the VIRTUAL machine. For example, in the HotSpot VIRTUAL machine version 1.7, the method area is called Permanent Space, while in JDK 1.8 it is called MetaSpace.
String constant pool
Not all constant pools are in the method area. Since JDK 7, String constant pools that were stored in the permanent generation have been moved to the Java heap. Running code in JDK1.8 does not cause method overflow (String:: Intern () is a native method, If the String constant pool already contains a String equal to this String, it returns a reference to the String in the pool. Otherwise, the String contained in this String is added to the constant pool and a reference to this String is returned.)
Public class RuntimeConstantPoolOOM_1 {public static void main(String[] args) { <String> Set = new HashSet<String>(); Short I = 0; short I = 0; while (true) { set.add(String.valueOf(i++).intern()); }}}Copy the code
Instead, use the -xmx parameter limit the maximum heap to 6 MB will be able to see – Xms6m – Xmx6m -xss128k – XX: + HeapDumpOnOutOfMemoryError – XX: HeapDumpPath = E: \ heapdumps
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.HashMap.newNode(HashMap.java:1750)
at java.util.HashMap.putVal(HashMap.java:631)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
at jvm.RuntimeConstantPoolOOM_1.main(RuntimeConstantPoolOOM_1.java:17)
Copy the code
JDK1.8 puts the string constant pool in the heap
Private parts
The Java heap and method area data are shared, but some parts are thread private. The thread private part can be divided into PC register, Java virtual machine stack and local method stack.
PC register (program counter)
The Program Counter Register is a small memory space that can be thought of as a line number indicator of the bytecode being executed by the current thread. In the conceptual model of Java virtual machine, bytecode interpreter works by changing the value of this counter to select the next bytecode instruction to be executed. It is an indicator of program control flow, and basic functions such as branch, loop, jump, exception handling and thread recovery depend on this counter.
Note: If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If the Native method is being executed, this counter value should be null. This memory region is the only one where the Java Virtual Machine Specification does not specify any OutOfMemoryError cases.
Why do I need a program counter?
Because multithreading in the Java VIRTUAL machine is implemented by the way threads alternate and allocate processor execution time, at any given time, one processor (or core for multi-core processors) will execute instructions in only one thread. Therefore, in order for threads to switch back to the correct execution position, each thread needs to have a separate program counter.
Java virtual machine stack
The Java virtual machine stack, which is created at the same time as the thread and has the same life cycle as the program counter, is called the stack and is used to store stack frames, i.e. local variables and the results of some procedures. The data stored in stack frame includes: local variable table, operand stack and other information.
Virtual machine Stack – Process details description
(1) each to create a thread, the virtual machine will create a virtual machine for the thread Stack, (2) the Java virtual machine Stack said method performs memory model, each call a method, it will generate a Stack Frame (Stack Frame) method is used to store the local variables, Stack operation, export information, when this method after the execution, The corresponding stack frame pops up.
Local method stack
Native method stacks are also used when Java virtual machines implement instruction set interpreters in other languages, such as C. If the Java virtual machine does not support the NatVIE method and does not rely on the traditional stack itself, you do not need to support the native method stack.
Direct memory
Direct Memory is not part of the run-time data area of the virtual machine, nor is it defined in the Java Virtual Machine Specification. But this part of memory is also frequently used and can cause OutofMemoryErrors, so we’ll cover it here.
【 reference 】 【 1 】 deep understanding of the Java virtual machine (3rd edition) [2] www.cnblogs.com/chanshuyi/p… 【 3 】 blog.csdn.net/weixin_4539…
This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.