This article is excerpted from the Third edition of understanding the Java Virtual Machine
An overview of the
Java virtual machine in the process of executing the Java program it’s managed by the data memory is divided into a number of different areas, these areas have their USES, and the time of creation and destruction, some areas with the start of the virtual machine process, some area is dependent on user thread start and end of the creation and destruction. Therefore, according to this characteristic, we can divide the region into two parts: thread public area and thread private area
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. The bytecode interpreter selects the next bytecode instruction to be executed by changing the value of the counter, and the execution flow of the program depends on this counter
Because Java virtual machine multithreading is executed by switching threads and allocating processor execution time, only one processor can execute instructions in one thread at a time. Each thread needs a separate program counter to ensure that it can be switched back to where it was executing. Therefore, the program counter is thread private, the counters between each thread do not affect each other, stored independently
If the thread is executing a Java method, the counter records the address of the virtual machine bytecode instruction being executed. If a local method is executed, the value corresponding to the counter is null. Program counters are the only area where OutOfMemoryError cases are not specified in the Java Virtual Machine specification, and for why, check out the official explanation below:
The Java Virtual Machine’s pc register is wide enough to hold a returnAddress or a native pointer on the specific platform
The Java virtual machine’s PC register is wide enough to hold a returnAddress or native pointer on a particular platform. That is, the program counter stores only a value that points to the location of the next instruction to be executed, and this value cannot exceed the range of THE PC register, so there is no memory overflow problem
Java virtual machine stack
The Java Virtual Machine Stack is also thread-private and describes the thread-memory model of Java method execution: When each method is executed, the Java VIRTUAL machine synchronously creates a Stack Frame to store information about local variables, operand stacks, dynamic connections, method exits, and so on. The process of each method being called and executed corresponds to the process of a stack frame going from the stack to the stack
The local variable table holds the various Java virtual machine base data types, object references, and returnAddresses that point to the address of a bytecode instruction that are known to the compiler. The storage space of these data types in the local variable table is represented by local variable slots, where the 64-bit long and double types occupy two slots and the rest occupy only one. The memory space required for the local variable table is allocated at compile time, and the size of the local variable table does not change during run time. This refers to the number of slots, and how much space a Slot occupies is up to the virtual machine
In the Java Virtual Machine specification, two types of exceptions are specified for this memory area: a StackOverflowError is thrown if the stack depth of a thread request is greater than the depth allowed by the virtual machine; An OutOfMemoryError will be raised if the Stack cannot allocate enough memory if the Java virtual machine stack can be dynamically expanded (HotSpot virtual machine cannot be dynamically expanded, so an OOM exception will be raised only if the thread fails to request stack space)
Local method stack
Native Method Stacks are similar to the virtual machine stack, except that the virtual machine stack services the execution of Java methods for the virtual machine, and the local Method stack is thread private
The Java Virtual Machine specification does not specify the language, usage mode, or data structure of the local method stack. The specific virtual machine can implement it as needed. The HotSpot VIRTUAL machine simply blends the local method stack with the virtual machine stack. Like the virtual stack, the local method stack throws StackOverflowError and OutOfMemoryError exceptions
The Java heap
The Java Heap is the largest area of memory managed by the VIRTUAL machine. It is shared by all threads. The sole purpose of this area is to hold object instances, and almost all object instances are allocated memory here
The Java heap is the area of memory managed by the garbage collector, so from a memory collection point of view, since most modern garbage collectors are designed based on generational collection theory, So the Java heap often has terms like “new generation”, “old age”, “permanent generation”, “Eden space”, “From Survivor space”, “To Survivor space”, etc. It is important to note that these areas are only a common feature or design style of a subset of garbage collectors, not a specific memory layout implemented by a Java virtual machine
According to the Java Virtual Machine specification, the Java heap can be in a physically discontiguous memory space, but must be considered logically contiguous. But for large objects (such as groups of objects), most virtual machines will most likely require contiguous arrays for simple implementation and efficient storage
Java heaps can be implemented as either fixed size or extensible (with arguments -xmx and -xms), raising OutOfMemoryError if there is no memory to allocate to the instance and the heap can no longer be extended
Methods area
The Method Area, like the Java heap, is a thread-shared Area that stores data such as type information that has been loaded by the virtual machine, constants, static variables, and code caches compiled by the just-in-time compiler. Although the Java Virtual Machine specification describes the method area as a logical part of the heap, it also has the nickname “non-heap” to distinguish it from the Java heap
How the method area is implemented depends on the implementation of the virtual machine and is not governed by the Java Virtual machine specification. In the case of the HotSpot VIRTUAL machine, the JDK8 method area was previously implemented using persistent generations, which are part of the JVM runtime memory area, allowing the HotSpot garbage collector to manage this memory as well as the Java heap
In retrospect, however, it was not a good idea to implement the method area using permanent generation, which makes Java applications more prone to running out of memory. For this, we need to set the upper limit of -xx :MaxPermSize. Back in JDK6, the HotSpot team had a plan to abandon the permanent generation and implement the method area in Native Memory (so as long as you don’t hit the machine Memory limit you won’t overflow). In JDK8, the concept of permanent generation is completely abandoned, and the meta-space implemented in local memory is replaced. The remaining content (mainly type information) in THE permanent generation in JDK7 is moved to the meta-space
Like the Java heap, the method area can even choose not to implement garbage collection, in addition to the fact that it does not require continuous memory and can choose to be fixed size or extensible. Garbage collection is relatively rare in this area, but that doesn’t mean garbage collection isn’t needed. The main goal of memory collection in this area is constant pool collection and type offloading. According to the Java VIRTUAL machine, OutOfMemoryError is thrown if the method area cannot meet the new memory allocation requirements
Run-time constant pool
The Runtime Constant Pool is part of the method area. The Constant Pool Table is used to store various literals and symbolic references generated at compile time. This part of the Table is stored in the runtime Constant Pool of the method area after the Class is loaded
The Java Virtual Machine specification does not specify any details about runtime constant pooling, and different virtual machines can implement it as needed. In general, in addition to saving symbolic references described in Class files, direct references translated from symbolic references are also stored in the runtime constant pool
Runtime constant pool relative to the Class files is an important feature of their constant pool is dynamic, the Java language does not require constant can only be produced at compile time, that is, into the Class files is not preset constant pool can enter into the content of the runtime constant pool method area, during the run can also be new constants in the pool, The most used is the String intern() method
Direct memory
Direct Memory is not part of the virtual machine’s run-time data area, but it is also frequently used and can cause OutofMemoryErrors
NIO class is new in JDK1.4. NIO is an I/O method based on channel Cancel and Buffer. It can allocate out-of-heap memory directly using Native functions. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory, both to improve performance and to avoid frequent exchanges between the Java heap and direct memory
The allocation of native direct memory is not limited by the JVM, but it is limited by the size of native memory and by the addressing space of the processor. When configuring VM parameters, the server administrator must also consider the direct memory and set proper parameters, such as -xmx