Deep understanding of JVM ==> runtime data area

1. Introduction to JVM

  JVM is an abbreviation of Java Virtual Machine (Java Virtual Machine). JVM is a specification for computing devices. It is a fictitious computer that is realized by simulating various computer functions on an actual computer.

  A very important feature of the Java language is its cross-platform nature. The use of Java virtual machine is the key to achieve this feature. If a general high-level language is to be run on different platforms, at least it needs to be compiled into different object codes. After the introduction of the Java language virtual machine, the Java language does not need to be recompiled when running on different platforms. The Java language uses the Java virtual machine to shield information related to specific platforms, so that the Java language compiler only needs to generate the target code (byte code) that runs on the Java virtual machine and can run on multiple platforms without modification . When the Java virtual machine executes bytecode, it interprets the bytecode as machine instructions on a specific platform. This is why Java can "compile once, run everywhere".

Two, JVM memory management model

Heap memory (Heap)

  For most applications, the Java Heap is the largest piece of memory managed by the Java Virtual Machine. The Java heap is a memory area shared by all threads and created when the virtual machine is started. The sole purpose of this memory area is to store object instances, where almost all object instances are allocated memory.

  Java heap memory can also be subdivided into: young generation and old generation. Among them, the young generation can be divided into Eden area, From Survivor space, To Survivor space, etc.

  If there is no memory in the heap to complete the instance allocation, and the heap can no longer expand, an OutOfMemoryError exception will be thrown.

Method Area

  The method area (method area), like the Java heap, is a memory area shared by various threads. It is used to store data such as class information, constants, static variables, and code compiled by the real-time compiler that have been loaded by the virtual machine. Although the Java virtual machine specification describes the method area as a logical part of the heap, it has an alias called Non-Heap (non-heap), the purpose should be distinguished from the Java heap.

  For developers who are used to developing and deploying programs on HotSpot virtual machines, many people are willing to call the method area "Permanent Generation". In essence, the two are not equivalent, just because of the HotSpot virtual machine's The design team chose to extend the GC generation collection to the method area, or use the permanent generation to implement the method area.

  The Java virtual machine specification has very loose restrictions on this area. In addition to the Java heap, which does not require contiguous memory and can be fixed or extensible, it can also choose not to implement garbage collection. Relatively speaking, garbage collection behavior is relatively rare in this area, but it is not that the data enters the method area as "permanently" exists as the name of the permanent generation. The goal of memory recovery in this area is mainly for the recovery of constant pools and the unloading of types. Generally speaking, the recovery "achievement" of this area is more difficult to satisfy, especially the type of unloading, the conditions are quite harsh, but this part of the area Recycling is indeed necessary.

  According to the Java Virtual Machine Specification, when the method area cannot meet the memory allocation requirements, an OutOfMemoryError exception will be thrown.

Program Counter (Program Counter Register)

  The program counter (Program Counter Register) is a small memory space, and its function can be regarded as the line number indicator of the bytecode executed by the current thread. In the conceptual model of the virtual machine (only the conceptual model, various virtual machines may be implemented in some more efficient ways), the bytecode interpreter works by changing the value of this counter to select the next one to be executed Bytecode instructions, branch, loop, jump, exception handling, thread recovery and other basic functions all need to rely on this counter to complete.

  Since the multi-threading of the Java virtual machine is implemented by thread switching and allocating processor execution time, at any given moment, a processor (for a multi-core processor, a core) will only execute one thread Instructions. Therefore, in order to restore the correct execution position after thread switching, each thread needs to have an independent program counter. The counters between each thread do not affect each other and are stored independently. We call this type of memory area "thread private "Memory.

  If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed; if the Natvie method is being executed, the counter value is empty.

  This memory area is the only one that does not specify any OutOfMemoryError in the Java Virtual Machine Specification.

Java Virtual Machine Stack (JVM Stacks)

  Like the program counter, the Java Virtual Machine Stack (Java Virtual Machine Stacks) is also private to the thread, and its life cycle is the same as the thread. The virtual machine stack describes the memory model of Java method execution: when each method is executed, a stack frame (Stack Frame) is created at the same time for storing local variable table, operation stack, dynamic link, method exit and other information. Each method is called until the execution is completed, which corresponds to a stack frame from the stack to the stack in the virtual machine stack.

  The local variable table stores various basic data types (boolean, byte, char, short, int, float, long, double), object references (reference type, which are not equivalent to the object itself, according to different virtual machines Implementation, it may be a reference pointer to the starting address of the object, it may also point to a handle representing the object or other location related to the object) and returnAddress type (pointing to the address of a bytecode instruction).

  Among them, the 64-bit long and double types of data will occupy 2 local variable spaces (Slot), and the remaining data types only occupy 1 slot. The memory space required by the local variable table is allocated during compilation. When entering a method, it is completely determined how much local variable space this method needs to allocate in the frame, and the size of the local variable table will not be changed during the execution of the method.

  In the Java virtual machine specification, two exception conditions are specified for this area: If the stack depth requested by the thread is greater than the depth allowed by the virtual machine, a StackOverflowError exception will be thrown. If the virtual machine stack can be dynamically expanded (most of the current Java virtual machines can be dynamically expanded, but the Java virtual machine specification also allows a fixed-length virtual machine stack), it will be thrown when enough memory cannot be applied for when expanding. OutOfMemoryError exception.

Native Method Stacks

  Native method stacks (Native Method Stacks) and virtual machine stacks play a very similar role, the difference is that the virtual machine stack executes Java methods (that is, bytecode) services for the virtual machine, while the local method stack is Native method service used by the virtual machine. The language, usage and data structure of the methods in the local method stack are not mandatory in the virtual machine specification, so the specific virtual machine can freely implement it. Some virtual machines (such as the Sun HotSpot virtual machine) directly combine the local method stack and the virtual machine stack into one. Like the virtual machine stack, StackOverflowError and OutOfMemoryError exceptions are thrown in the local method stack area.

Runtime Constant Pool

  The constant pool is part of the method area. In addition to the class version, fields, methods, interfaces, and other description information in the Class file, there is also a constant pool, which is used to store various literals and symbol references generated by the compiler. This part of the content will be stored in the runtime constant pool of the method area after the class is loaded.

  An important feature of the runtime constant pool is its dynamic nature. The Java language does not require constants to be generated only at compile time, that is, the contents of the constant pool in the Class file are not preset to enter the runtime constant pool of the method area. During the period, new constants can also be put into the constant pool. This feature is often used by developers is the intern () method of the String class.

  Since the constant pool is part of the method area at runtime, it is naturally limited by the memory of the method area. When the constant pool cannot apply for memory, an OutOfMemoryError exception will be thrown.

Direct memory

  Direct memory is not part of the virtual machine runtime data area, nor is it the memory area defined in the Java virtual machine specification. However, this part of memory is also frequently used, and it can also cause OutOfMemoryError, so it is introduced here.

  In JDK1.4, the NIO (New Input / Output) class was newly added, and an I / O method based on Channel and Buffer was introduced. It can directly allocate off-heap memory using the Native function library, and then A DirectByteBuffer object stored in the Java heap is used as a reference to this memory to avoid copying data back and forth in the Java heap and the Native heap, which can significantly improve performance in some scenarios.

  Direct memory allocation will not be limited by the Java heap memory, but will be limited by the total memory size of the machine and the addressing space of the processor. When setting the virtual machine parameters, the server administrator sets the parameter information such as -Xms and -Xmx according to the actual memory, but often ignores the direct memory, so that the sum of each memory area is greater than the physical memory limit, resulting in an OutOfMemoryError exception during dynamic expansion.

Guess you like

Origin www.cnblogs.com/L-Test/p/12736914.html