Java runtime data area
The memory managed by the Java virtual machine contains the following runtime data areas, as shown:
- Program counter
- Java virtual machine stack
- Local method stack
- The Java heap
- Methods area
1. Program counter
A program counter is a relatively small memory space that is a line number indicator of the bytecode being executed by the current thread.
1.1 Function of program counter
Because multithreading in the Java virtual machine is implemented by switching threads and allocating processor execution time, only one processor will execute instructions in one thread at any given time. Therefore, in order to restore the thread to the correct execution position after switching, each thread needs to have an independent program counter. Counters between each thread do not affect each other and are stored independently. This kind of memory area is “thread private” memory.
1.2 Features of the program counter
-
It’s a small memory space.
-
Threads are private; each thread has its own program counter.
-
Life cycle: Created as a thread is created and destroyed as a thread terminates.
-
Is the only memory region where OutOfMemoryError does not occur.
2 Java VM stack
2.1 Java Virtual Machine Stack Definition
The Java virtual machine stack is thread-private, and its lifecycle is the same as that of a thread. The virtual machine stack describes the thread-memory model of Java method execution.
Each time a method is executed, the Java virtual machine synchronously creates a war to store some information during the execution of the method:
- Local variable scale
- Java VM basic data types (Boolean, byte, CHAR, short, int, float, long, double).
- Object reference;
- returnAddress ;
- The operand stack
- Dynamic connection
Each stack frame contains a reference to the method in the runtime constant pool to which that stack frame belongs, which is held to support Dynamic Linking during method invocation.
- Methods the export
Once a method has started executing, there are only two ways to exit. One is to encounter bytecode instructions returned by the method. One is to encounter an exception that is not handled in the method body.
- .
Each method is called until the completion of the process corresponds to a stack frame in the virtual machine from the stack to the stack process.
2.2 Features of the Java Virtual Machine Stack
- The memory space required for the local variable table is allocated at compile time, and when entering a method, the amount of local variable space that the method needs to allocate in the stack frame is fully determined and does not change the size of the local variable table during the method run.
- There are two exceptions to the Java virtual machine stack:
StackOverflowError
和OutOfMemoryError
- If the thread requests a station depth greater than the depth allowed by the virtual machine, it is thrown
StackOverflowError
; - If the Java virtual machine station capacity can be dynamically expanded, it will be thrown when the stack cannot allocate enough memory
OutOfMemoryError
The exception.
- If the thread requests a station depth greater than the depth allowed by the virtual machine, it is thrown
3. Local method stack
The role of the local method stack is similar to that of the virtual machine, except that the virtual machine executes Java methods for the virtual machine, while the local method stack serves the use of local methods for the virtual machine.
3.1 Characteristics of the local method stack
- There are two exceptions to the Java virtual machine stack:
StackOverflowError
和OutOfMemoryError
- If the thread requests a station depth greater than the depth allowed by the virtual machine, it is thrown
StackOverflowError
; - If the Java virtual machine station capacity can be dynamically expanded, it will be thrown when the stack cannot allocate enough memory
OutOfMemoryError
The exception.
- If the thread requests a station depth greater than the depth allowed by the virtual machine, it is thrown
4. The Java heap
4.1 Java heap Definition
The Java heap is the largest chunk of memory managed by the virtual machine. The Java heap is an area of memory that is shared by all threads and is created when the virtual machine is started. The sole purpose of this memory area is to hold object instances, and “almost” all object instances in Java are allocated memory here. The use of “almost” is due to the development of the Java language, just-in-time compilation, the growing power of escape analysis, on-stack allocation, scalar substitution and other optimizations that make it less absolute that Java object instances are allocated on the heap. The Java heap is the primary area managed by the garbage collector and is often referred to as the “GC heap”. From the point of view of memory reclamation, since collectors now use generational collection algorithms (which have changed since G1, introducing regions, but still using generational ideas), the Java heap can also be subdivided into: New generation and old generation. More detailed are Eden space, From Survivor space, ToSurvivor space, etc. From the perspective of memory Allocation, the Java heap shared by threads may have multiple Thread private Allocation buffers (TLabs).
4.2 Heap area adjustment
According to the Java Virtual Machine specification, the Java heap can be in a physically discontinuous memory space, as long as it is logically contiguous, like our disk space. This can be either fixed size at implementation time or dynamically adjusted at run time.
Adjust the parameters
You can set the initial and maximum values of the heap size by setting the following parameters, for example:
-Xms256M -Xmx 1024M
Where -x is the JVM runtime parameter, MS is short for Memory start, mx is short for memory Max.
PS: Under normal circumstances, the heap space is constantly expanding and shrinking while the server is running, which can cause unnecessary system stress. Therefore, the Xms and Xmx of the JVM in the online production environment are set to the same size to avoid the extra stress caused by adjusting the heap size after GC.
4.3 OOM abnormal
The size of the heap can be fixed or expanded, but for mainstream virtual machines the size of the heap is extensible, so OutOfMemoryError is thrown when the thread requests memory allocation but the heap is full and can no longer be expanded.
/** * VM Args: -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError */ public class HeapOOMTest { public static final int _1MB = 1024 * 1024; public static void main(String[] args) { List<Integer[]> list = new ArrayList<>();for(int i = 0; i < 10; i++) { Integer[] ints = new Integer[2 * _1MB]; list.add(ints); }}}Copy the code
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid32372.hprof ...
Heap dump file created [7774077 bytes in 0.009 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at jvm.HeapOOMTest.main(HeapOOMTest.java:18)
Copy the code
5. Methods area
Like the Java heap, the method area is an area of memory shared by each thread. It is used to store information about classes that have been loaded by the virtual machine, constants, static variables, and code caches compiled by the just-in-time compiler.
In the HotSpot JVM, the persistent generation (the persistent generation implementation Method area) is used to hold metadata for classes and methods, as well as constant pools such as Class and Method. Whenever a class is first loaded, its metadata is put into the persistent generation. Permanent generation has a size limit, so if the loaded classes is too much, will likely result in the permanent generation of memory, Java. Lang. OutOfMemoryError: PermGen, therefore we have to do to the virtual machine tuning. Later HotSpot abandoned PermGen. In jdk1.7 HotSpot removed the string constant pool, static variables and so on from the PermGen. In jdk1.8 HotSpot completely abandoned PermGen and moved the method area to Metaspace. Such as class meta information, fields, static properties, methods, constants, and so on are all moved to the metasespace area. Similar in nature to permanent generations, meta-spaces are implementations of method areas in the JVM specification. However, the biggest difference between a meta-space and a permanent generation is that the meta-space is not in the virtual machine, but uses local memory. Therefore, by default, the size of the meta-space is limited only by local memory.
5.1 Corresponding JVM Parameters:
parameter | role |
---|---|
-XX:MetaspaceSize | The initial size assigned to Metaspace (in bytes). If not set, the default is 20.79 MB, This initial size is the threshold that triggers the first Metaspace Full GC, such as -xx :MetaspaceSize=256M |
-XX:MaxMetaspaceSize | The maximum value assigned to Metaspace, beyond which Full GC is triggered, There is no limit to this value by default, but it should depend on the size of system memory. The JVM changes this value dynamically. However, you are advised to set this parameter for online environments, for example, -xx :MaxMetaspaceSize=256M |
-XX:MinMetaspaceFreeRatio | Minimum free ratio, the Metaspace free ratio is calculated after Metaspace GC occurs. If the free ratio (free space/current Metaspace size) is less than this value, Metaspace will be triggered to expand. The default value is 40, which is 40%, For example – XX: MinMetaspaceFreeRatio = 40 |
-XX:MaxMetaspaceFreeRatio | Maximum free ratio, the free ratio of Metaspace is calculated after Metaspace GC occurs. If the free ratio (free space/current Metaspace size) is greater than this value, That triggers Metaspace to free up space. The default value is 70, which is 70%, For example – XX: MaxMetaspaceFreeRatio = 70 |
You are advised to set MetaspaceSize and MaxMetaspaceSize to the same size to avoid frequent expansion.
5.2 OOM abnormal
OutOfMemoryError is thrown if the method area cannot meet the new memory allocation requirements.
5.3 Runtime constant pool
Runtime constant pool is part of the method, in addition to the Class file has a version of a Class, field, method, interface description information, such as there is a information is constant pool table, used to store generated during compilation of literal and symbolic references, this part will deposit after Class loading to the method of runtime constants in the pool.
The method area holds: class information, constants, static variables, and just-in-time compiler compiled code. Constants are stored in the runtime constant pool. When a class is loaded by the Java Virtual machine, constants in the.class file are stored in the runtime constant pool of the methods area. And at run time, new constants can be added to the constant pool. The intern() method of the String class, for example, adds String constants to the constant pool at run time.
6. Direct memory
Direct memory is not part of the virtual machine’s run-time data area. NIO introduced a channel – and buffer-based IO approach. It can directly allocate memory outside of the Java VIRTUAL machine by calling local methods, and then manipulate that memory directly through a DirectByteBuffer object stored in the heap, rather than copying data from external memory to the heap, thus improving the efficiency of data manipulation. The size of direct memory is not controlled by the Java virtual machine, but since it is memory, OutOfMemoryError is thrown when there is insufficient memory.
6.1 Direct memory vs. heap memory
- Direct memory requisition space costs higher performance;
- Direct memory reads IO better than ordinary heap memory.
- Direct memory function chain: local IO -> Direct memory -> Local IO
- Heap memory chain: local IO -> Direct memory -> Indirect memory -> Direct memory -> local IO
When configuring VM parameters, the server administrator sets parameters such as -xmx based on the actual memory. However, the direct memory is often ignored. As a result, the sum of memory regions is greater than the physical memory limit, and an OutOfMemoryError occurs during dynamic expansion.
reference
- Deep Understanding of the Java Virtual Machine (3rd edition) – Zhou Zhiming
- Dive into the JVM-memory model
- Beautiful graphics guide you to understand the JVM memory layout
- JVM memory model