Today’s sharing started, please give us more advice ~
JVM runtime data area
- Thread the exclusive
Each thread has its own space, which is created and destroyed with the thread life cycle
- Threads share
All threads have access to this memory data, which is created and destroyed with the VIRTUAL machine or GC
1 Program Counter Register
The name Register comes from the CPU’s Register, which the CPU can run only if it loads data into it
The register stores the field information related to the instruction. Due to the LIMITATION of THE CPU time wafer wheel, a processor or a core in a multi-core processor will execute only one instruction in a certain thread at any given moment during the concurrent execution of many threads. This will inevitably lead to frequent interruptions or recovery, how to ensure that there is no difference?
After each thread is created, it will generate its own program counter and stack frame. Program counter is used to store the offset and line number indicator of the execution instruction. The thread execution or recovery depends on the program counter. Program counters do not affect each other between threads, and no out-of-memory exceptions occur in this area.
Definition 1.1.
This is a small memory space that can be used as a line number indicator of the bytecode being executed by the current thread. If the current thread is executing:
- Java method
The counter records the address of the bytecode instruction being executed by the current thread
- Local method
The program counter value is undefined
1.2. Effect of
Program counters (hereafter referred to as PCR) serve two purposes:
- Bytecode interpreter realizes the process control of code by changing PCR to read instructions in sequence, such as sequential execution, selection, loop and exception handling
- In the case of multiple threads, PCR is used to record where the current thread is executing so that when the thread is switched back it can know where it was last run
Characteristics of 1.3.
A small area of memory [thread private]. Each thread has a separate program counter.
The only memory area that will not appear in the OOM.
Java Virtual Machine Stack (JVM Stack)
Definition 2.1.
The JVM is a stack-based environment as opposed to a register-based environment. The stack structure is more portable and controllable.
The virtual stack in the JVM is the area of memory that describes the execution of Java methods and is thread private.
The elements in the stack are used to support the virtual machine to make method calls. The process from the beginning of each method call to the completion of execution is the process from the stack frame to the stack frame.
3. Native Method Stack
Similar to the virtual stack function, the virtual stack is prepared for the virtual machine to execute JAVA methods
The virtual machine specification does not specify specific implementations, which are implemented by different virtual machine vendors.
The implementation of the virtual machine stack and the local method stack is the same in the HotSpot virtual machine. Again, beyond the size
StackOverflowError is also thrown.
The native method stack and the Java virtual machine stack implement almost the same functionality as throwing exceptions
However, the virtual machine stack serves Java methods (that is, bytecode) executed by the virtual machine, while the local method area serves Native methods used by the virtual machine.
In the JVM memory layout, thread objects are also private, but the virtual stack is “main in” and the local method stack is “main out”
This “internal and external” is specific to the JVM, and the Native method stack serves the Native method
When threads start calling local methods, they enter a world that is no longer bound by the JVM
Local methods can access the data area of the virtual machine through the Java Native Interface (JNI), and even call registers, with the same capabilities and permissions as the JVM
When a large number of native methods occur, the JVM’s control over the system is bound to be weakened because of its black-box error messages.
In the case of running OutOfMemory, the native heap OutOfMemory is still thrown by the native method stack
The best known native method is System.CurrentTimemillis (), where JNI enables Java to make deep use of OS features and reuse non-Java code
However, if JNI is implemented in a large number of other languages during the project, it will lose its cross-platform characteristics and threaten the stability of the application
If you need to interact with native code, you can use an intermediate standard framework to decouple it so that a native method crash does not affect the stability of the JVM
Of course, if you require high execution efficiency, low-level cross-process operations, etc., you can consider designing JNI calls
2.2 structure
Stack frames are the basic structure in which methods are run.
- In an active thread, only the frame at the top of the stack is valid, called the current stack frame
- The method being executed is called the current method
When the execution engine is running, all instructions can only operate on the current stack frame, and a StackOverflowError indicates a stack overflow of a request resulting in a memory depletion, usually in recursive methods.
The stack frames of the current method are all battlefields where the operation stacks are soldiers participating in the battle
Operation of the stack push and out of the stack
Virtual machine stack by pressing/out of the stack, each method corresponding to the active stack frame operation processing, the normal execution of the method, will definitely jump to another stack frame.
In the process of execution, if there is an exception, it will backtrace the exception, and the return address is determined by the exception handling table.
Stack frames play a very important role in the entire JVM system, including: local variable table, operation stack, dynamic link, method return address, etc.
Local variable scale
Store method parameters and local variables.
Local variables have no preparation phase and must be explicitly initialized, as opposed to the preparation and initialization phases of class attribute variables.
If the method is non-static, the instance reference of the object to which the method belongs is stored at the index[0] position, followed by parameters and local variables.
The STORE instruction in the bytecode instruction is to write the local variable calculated in the operation stack back into the storage space of the local variable table.
The operand stack
A bucket stack whose initial state is empty. Since Java has no registers, all arguments are passed using the operand stack. During method execution, various instructions write and extract information onto the stack. The EXECUTION engine of the JVM is a stack-based execution engine, where the stack refers to the operation stack.
The bytecode instruction set is defined based on the stack type, and the depth of the stack is in the stack property of the method meta-information.
The operation stack interacts with the local variable table
The detailed order of bytecode operations is as follows:
The bytecode instruction istore_ 1 isto open the no. 1 drawer and store the number 13 at the top of the stack. The stack is a deep vertical bucket, and only the barrel opening elements can be operated at any time. So data can only be accessed at the top of the stack.
Some instructions can be performed directly in the drawer, such as the INC instruction, which performs a +1 operation on the value in the drawer
The difference between I ++ and ++ I, common in programmer interviews, can be contrasted with bytecodes
- Iload_ 1 takes a number from the first drawer of the local variable table and pushes it to the top of the stack. The next step isto perform the +1 operation directly in the drawer. This operation has no effect on the value of the top element, so istore_ 2 simply assigns the top element to A
- In the right column of the table, the +1 operation is performed in drawer 1, and then iload_ 1 pushes the number in drawer 1 to the top of the stack, so istore_ 2 stores the value after +1. I++ is not an atomic operation. Even with the volatile keyword, multiple threads writing at the same time can cause data overwrite each other.
Dynamic connection
Each stack frame contains a reference to the current method in the constant pool to support dynamic concatenation during method calls.
Method return address
There are two exits when a method executes:
- The normal exit
RETURN bytecode instructions normally executed to any method, such as RETURN, IRETURN, ARETURN, etc.
- Abnormal exit
Either way, it returns to where the method was currently called. Method exit is equivalent to popping up the current stack frame.
There are three possible ways to exit:
- The return value is pressed into the upper call stack frame
- The exception message is thrown to a stack frame that can handle it
- The PC counter points to the next instruction after the method call
The Java virtual machine stack is an in-memory model that describes how Java methods run. The Java virtual machine stack creates “stack frames” for each Java method to be run. Used to store some information that the method needs to run.
- Local variable table: stores variables of basic data type, variables of reference type, and variables of returnAddress type
- The operand stack
- Dynamic link
- Constant pool pointer to the current method
- The return address of the current method
- Method export and other information
Each method, from being called to being executed, corresponds to the process of a stack frame in and out of the JVM stack
Note: It is often said that Java’s memory space is divided into “stacks” and “heaps,” with local variables in the stack and objects in the heap.
That’s not entirely true! The “heap” here can be understood that way, but the “stack” here is the virtual machine stack, or the local variable table part of the Java virtual machine stack.
The real Java virtual machine stack is made up of stack frames, and each stack frame has: local variable table, operand stack, dynamic link, method exit information.
The characteristics of
The local variable table is created as the stack frame is created when the method is executed.
The size of the table is determined at compile time, and only a predetermined size is allocated at creation time. The size of the table does not change as the method runs. There are two exceptions to the Java virtual machine stack:
StackOverFlowError
If the memory size of the Java virtual machine stack does not allow dynamic scaling, this exception is thrown when the stack depth requested by the thread is greater than the maximum depth allowed by the virtual machine (but there may be more memory)
The maximum stack memory is 1 MB by default, exceeding which a StackOverflowError is thrown
OutOfMemoryError
OutOfMemoryError is raised if the memory size of the Java virtual machine stack allows dynamic expansion, and the memory is exhausted when the thread requests the stack and cannot be dynamically expanded
The Java virtual machine stack is also thread-private, with each thread having its own Java virtual machine stack that is created as the thread is created and dies as the thread dies.
4 Java Heap
Created when the JVM starts to hold instances of objects. The garbage collector mainly manages heap memory.
The Heap is the primary source of OOM failures. It stores almost all instance objects. The Heap is automatically collected by the garbage collector, and the Heap area is shared by child threads
It usually takes up the most space of any memory region, but can easily run out of space if you create a large number of objects inordinately
The memory space of the heap can be either fixed size or dynamically adjusted at runtime, with initial and maximum values set with parameters such as
-Xms256M. -Xmx1024M
Where -x indicates that it is a JVM run parameter
- Ms is short for MemoryStart Minimum Heap Capacity
- Mx is short for Memory Max maximum heap capacity
However, in most cases, the heap space is constantly expanding and shrinking while the server is running, which inevitably causes unnecessary system stress. Therefore, in online production environments, THE Xms and Xmx of the JVM are set to be the same size to avoid extra stress when the heap size is adjusted after GC
The heap is divided into two big blocks: Cenozoic and old age
Objects are generated in the new generation at the beginning, and enter the old age when they enter the old age, but the old age also accepts large objects that cannot be accommodated in the new generation
New generation = 1 Eden region + 2 Survivor region
Most objects are generated in Eden, and when Eden is filled, the Young GC is triggered. During garbage collection, the clearing policy is implemented in Eden area, and objects that are not referenced are directly collected. The surviving objects are moved to the Survivor zone, which literally exists
S0 and S1, which space is Survivor? On each Young GC, live objects are copied to the unused space, and the currently in use space is cleared completely, switching the usage of the two Spaces
If the object YGC wants to move is larger than the upper limit of Survivor capacity, it is handed over directly to the older generation
It would be a mistake for a few unmotivated players to think they could keep swapping in the Survivor zone of the new generation. Each object has a counter, and YGC increments by 1 each time.
-XX:MaxTenuringThreshold
Parameter can be configured when the value of the counter reaches a certain threshold, the object is promoted from the new generation to the old generation. If this parameter is set to 1, the Eden area of the Cenozoic era is moved to the old era. The default value is 15 and can be promoted to the old age after 14 swaps in Survivor zones
If the Survivor zone cannot be laid down, or the threshold of the super-large object exceeds the upper limit, allocation is attempted in the old age.
Full Garbage Collection(Full GC) is triggered if the old years cannot be laid down;
If you still can’t put it down, throw OOM.
The heap has the highest OOM probability of any out-of-memory exception
The heap information when an error occurs can be very helpful in resolving the problem, so set the JVM to run parameters –
XX:+HeapDumpOnOutOfMemoryError
Enable the JVM to output heap information when encountering an OOM exception
Heap memory is divided differently in different JVM implementations and different reclamation mechanisms
Store all class instances and array objects
In addition to instance data, other information about the object is saved, such as Mark Word (store object hash code, GC flag, GC age, synchronization lock, etc.), Klass Pointy(pointer to storage type metadata), and some padding data with byte alignment (if the instance data is exactly 8 byte alignment, there is no padding).
The characteristics of
The largest chunk of memory that the Java virtual machine needs to manage.
Heap memory does not have to be physically contiguous, just logically contiguous, just like disk space.
The heap is the main area of garbage collection, so it is also referred to as the GC heap.
The size of the heap can be fixed or expanded, but the mainstream virtual machine heap is scalable (controlled by -xmx and -xMS), so OutOfMemoryError is thrown when the thread requests memory allocation but the heap is full and cannot be expanded.
Threads share
The entire Java virtual machine has only one heap, and all threads access the same heap.
It is an area of memory that is shared by all threads and is created when the virtual machine starts.
The program counter, Java virtual machine stack, and local method stack are all one thread at a time
Five methods area
5.1 define
The method area defined in the Java virtual machine specification is a logical division part of the heap, the specific implementation is based on different virtual machines to achieve, for example: HotSpot in Java7 method area in the permanent generation, Java8 in the metadata space, and through the GC mechanism to manage this area.
Alias non-heap to distinguish it from the Java Heap. The method area stores the files that have been loaded by the VM:
- The class information
- constant
Constants are stored in the Runtime Constant Pool.
- A static variable
Data such as just-in-time (JIT) compiled code
5.2 the characteristics of
- Threads share
The method area is a logical part of the heap and, like the heap, is shared by threads. There is only one method area in the entire virtual machine.
- The permanent generation
The information in the method area generally needs to exist for a long time, and it is the logical partition of the heap, so with the partition method of the heap, we call the method area permanent generation.
- The memory reclamation efficiency is low
The Java Virtual Machine specification is lax about method areas, and garbage collection can be omitted.
The information in the method area is usually persistent, and only a small amount of information may be invalid after the memory is reclaimed.
The primary goal of memory reclamation for the method area is to reclaim the constant pool and unload the type
Like the heap, fixed size is allowed, scalable size is allowed, and garbage collection is not allowed.
OutOfMemoryError is thrown when the method area memory space cannot meet the memory allocation requirements.
5.3 Runtime Constant Pool
5.3.1 definition
Part of the method area.
The.class file generated after the compilation of.java files contains: class version, fields, methods, interfaces, and other description information, as well as a constant pool.
All contents of the constant pool in the.class file are stored in the runtime constant pool in the method area after the class is loaded.
In JDK6, 7, and 8, the region of the runtime constant pool is constantly changing:
- At 6, is part of the method area
- At 7, it goes to the heap again
- At 8 o ‘clock, the meta-space appears and the method area is returned
This also shows that the official optimization of the “permanent generation” has been underway since 7.
5.3.2 features
Another feature of the runtime constant pool over the Class file constant pool is that it is dynamic. The Java language does not require that constants must be generated only by the compiler. That is, constants that are not preset into the class file constant pool can be entered into the method area runtime constant pool, and new constants may be added to the pool at runtime.
The Intern () method of the String class takes advantage of the runtime constant pool dynamics. When the intern method is called, see that the pool already contains a String equal to this String:
- is
Returns a string from the pool
- no
Adds this String to the pool and returns a reference to this String
5.3.3 Possible Exceptions
The runtime constant pool is part of the method area and is therefore limited by method area memory, so OutOfMemoryError is thrown when the constant pool can no longer claim memory.
We usually declare a constant ina class through public static final. This Class is compiled to generate a Class file in which all information about the Class is stored.
When the class is loaded by the Java Virtual machine, the constants in the class file are stored in the runtime constant pool in the methods area. And at run time, new constants can be added to the constant pool. For example, the Intern () method of the String class adds String constants to the constant pool at run time.
When some constants in the run-time constant pool are not referenced by objects and are not referenced by variables, then the garbage collector needs to collect them.
6 Direct Memory
Direct memory is not part of the run-time data area of the VIRTUAL machine, nor is it an area of memory defined in the JVM specification, but it is frequently used during the actual running of the JVM. And I’m also going to flip OOM
NIO(New) was added in JDK 1.4 The Input/Output class introduces a pipe-based and buffer-based IO approach, which can use Native libraries to allocate out-of-heap memory directly, and then manipulate data in out-of-heap memory through a DirectByteBuffer object stored in the heap as a reference to that memory.
This can significantly improve performance in some scenarios because it avoids copying data back and forth between the Java heap and Native heap.
All this seems to be
The program counter, Java virtual machine stack, and local method stack are thread private, that is, each thread has its own program counter, Java virtual machine stack, and local method area. And their life cycle is the same as the thread they belong to.
While the heap and method area are shared by threads, there is only one heap and one method stack in the Java VIRTUAL machine. It is created when the JVM starts and destroyed when the JVM stops.
7 Metaspace
In JDK8, the precursor of the meta space, the Perm area (permanent generation), was phased out. In JDK7 and previous versions, only Hotspot had the Perm area, which was fixed in size at startup, difficult to tune, and moved the class meta information when Full GC was used.
In some scenarios, if too many classes are dynamically loaded, OOM in the Perm area is generated. For example, because there are many function points in a project, many classes need to be dynamically loaded during operation, and errors often occur:
To solve this problem, you need to set the running parameters
-XX:MaxPermSize= l280m
If you deploy to a new machine, the failure will often recur because JVM parameters have not been modified. People unfamiliar with the app had a hard time troubleshooting the problem. In addition, persistent generation has many problems in GC.
So, JDK8 uses meta-space to replace permanent generations. Unlike permanent generation, meta-space is allocated in local memory. That is,
As long as local memory enough, it won’t appear similar to the permanent generation of Java. Lang. OutOfMemoryError: PermGen space
The PermSize and MaxPermSize Settings for the permanent generation are also disabled. In JDK8 and later, if you set the MaxPermSize parameter, the JVM will not report an error at startup, but will tell you:
Java HotSpot 64Bit Server VM warning:ignoring option MaxPermSize=2560m; support was removed in 8.0
By default, the size of the “metaspacesize” can be adjusted dynamically, or the new parameter MaxMetaspaceSize can be used to limit how much local memory can be allocated to class metadata.
In JDK8, all content in the Perm section
- String constants are moved to heap memory
- Other content, including class meta-information, fields, static properties, methods, constants, and so on, is moved into the meta-space
For example, the Object meta information, static property System.out, integer constant 000000, etc
The actual object of the String shown in the figure in the constant pool is stored in heap memory.
Meta-spatial characteristics
- Take full advantage of the Java language specification: the life cycle of classes and associated metadata is consistent with that of the class loader
- Each class loader has its own area of memory – the meta-space
- It’s just a linear assignment
- Never reclaim a single class (except for RedefineClasses or class loading failures)
- No GC scanning or compression
- Objects in the meta space are not transferred
- If the GC finds that a class loader is no longer alive, the entire meta-space is collectively reclaimed
GC
- During Full GC, Pointers to metadata are no longer scanned, reducing Full GC time
- Much of the complex metadata scanning code (especially in the CMS) has been removed
- The meta-space has only a few Pointers to the Java heap
- This includes: Pointers to instances of java.lang.Class in the metadata of the Class; Pointer to the java.lang.Class collection in the metadata of the array Class.
- There is no metadata compression overhead
- Reduced GC Root scanning (no longer scanning directories of loaded classes and other internal hash tables in the virtual machine)
- In G1, classes can be unloaded once the concurrent marking phase is complete
Meta – space memory allocation model
- Most of the space for class metadata is allocated in local memory
- Objects used to describe class metadata are also removed
- Multiple mapped virtual memory Spaces are allocated for metadata
- Each class loader is assigned a list of memory blocks
- The size of the block depends on the type of class loader
- Java reflection of the bytecode accessors (sun.reflect.delegatingclassloaders) smaller footprint
- Free block memory is returned to the block memory list
- When the meta-space is empty, the virtual memory space is reclaimed
- Reduced memory fragmentation
Finally, from the perspective of thread sharing
- The heap and meta-space are shared by all threads
- The virtual machine stack, local method stack, and program counter are private within the thread
Take a look at the Java memory structure from this perspective
Look at the Java heap from a GC perspective
The heap and method areas are shared by threads and are used to store information about objects. Multiple implementation classes in an interface may require different amounts of memory, and branches in a method may require different amounts of memory. We don’t know what objects will be created until the program is running. Therefore, this part of memory and reclamation are dynamic. This is the part of memory that the garbage collector is concerned with (and only this part of memory is referred to as “memory” allocation and reclamation later in this section). This portion of memory is allocated differently in JDK1.7 and 1.8:
The heap memory allocation in Java8 looks like this:
9 the JVM closed
- Normal shutdown: When the last non-daemon thread terminates or calls System.exit or in some other platform-specific way, such as CTRL + C.
- Force shutdown: Call the Runtime.halt method, or kill the JVM process in the operating system.
- Exception Shutdown: RuntimeException is encountered during running
In some cases, we need to do some cleaning when the JVM is shut down, such as deleting temporary files and stopping the logging service. For this, the JVM provides shutdown hocks to do these events.
The Runtime class encapsulates the Runtime environment of a Java application. Each Java application has an instance of the Runtime class, and users can connect to the Runtime environment.
A closing hook is essentially a Thread (also known as a HOCK Thread) that registers a closing hook with the main JVM via the Runtime addShutdownhock (Thread Hock). The Hock thread executes when the JVM is normally shut down, forcing the shutdown not to execute.
For multiple closed hooks registered in the JVM, they execute concurrently, and the JVM does not guarantee their execution order.
summary
Memory is a very important system resource. It is the intermediate warehouse and bridge between hard disk and CPU, carrying the operating system and application program running in real time.
The JVM memory layout defines the Java memory allocation, allocation, and management strategies during the running process, ensuring efficient and stable running of the JVM. There are some differences in how memory is divided and managed by different JVMS. The classical JVM memory layout is explored in conjunction with the JVM virtual machine specification.
Today’s share has ended, please forgive and give advice!