When a Java virtual machine runs a Java program, the memory it manages is divided into several different data areas, including the following five parts: program counters, Java heap, Java virtual machine stack, method area, and local method stack.

JVM memory structure

Program counter

The program counter is a line number indicator of the bytecode executed by the current thread. It indicates the address of the next instruction to be executed. The bytecode interpreter selects the next operation by changing the value of the counter.

A program counter is a small piece of memory that is private to the thread. Each thread must have a separate program counter to restore the thread to the correct execution position after switching.

  • If the thread is executingJavaMethod, the counter records the address of the virtual machine bytecode instruction being executed
  • If you executenativeMethod, the counter is empty

It is also the only memory region where outofMemoryErrors do not occur.

Java virtual machine stack

Like the program counter, the Java virtual machine stack is thread private. When a thread is created, the Java stack is created. Each method is executed with a stack frame that holds information about local variables, operand stacks, dynamic links, method exits, and so on. Each method, from invocation to execution, corresponds to the process of a stack frame in the virtual machine stack and out of the stack.

The “stack” refers to the local variable table part of the virtual machine stack, which stores various basic data types (eight types), object references (reference types) and returnAddress types. The space required for a local variable table is determined and allocated at compile time and does not change during a method run.

There are two possible exceptions in the Java virtual stack:

  • StackOverflowError: Thread request stack depth is greater than the depth allowed by the virtual machine
  • OutOfMemoryError: Failed to apply for sufficient memory during vm stack expansion

Local method stack

The function of the local method stack is similar to that of the Java virtual machine stack, except that the Java virtual machine stack executes Java methods for the VIRTUAL machine, while the local method stack executes Native methods for the virtual machine. Some virtual machines, such as the HotSpot VIRTUAL machine, simply merge the local method stack with the Java virtual machine stack.

StackOverflowError and OutOfMemoryError exceptions may also be thrown by the local method stack.

The Java heap

The Java heap is the primary memory area in the virtual machine. It is shared by threads, created at virtual machine startup, and almost all object instances are stored in the Java heap.

The Java heap is also known as the “GC” heap. From the point of view of memory recycling, can be divided into the new generation and the old age. The New generation can be divided into Eden zone, From Survivor zone, To Survivor zone, etc.

Java heap implementations can be either fixed or extended. Current virtual machines are implemented as extensible, with -xmx and -xms controlling the heap size.

OutOfMemeoryError is raised if there is no memory in the heap and no further expansion is possible.

Methods area

The method area, like the Java heap, is shared by threads. Used to store information about classes that have been loaded by the virtual machine, constants, static variables, code compiled by the just-in-time compiler, and so on. Also called non-heap.

OutOfMemoryError is thrown if the method area cannot meet memory allocation requirements.

Run-time constant pool

The runtime constant pool is part of the method area. The constant pool in the Class file is used for the various literal and symbolic references generated at compile time, which are stored in the runtime constant pool after the Class is loaded.

Dynamic nature is an important feature of the runtime constant pool as opposed to the Class file constant pool, i.e. constants are not required to be generated only at compile time, and new constants can be put into the pool at run time.

The runtime constant pool is limited by method area memory, and an OutOfMemoryError is thrown if the constant pool can no longer claim memory.

Direct memory

Direct memory is not managed by the JVM. It is allocated memory area outside the Java heap using the Native function library, which can avoid copying data between the Java heap and Native heap to improve performance.

NIO’s DirectByteBuffer, for example, can be used as a reference to direct memory.

Permanent generation and meta-space

Method regions are sometimes referred to as permanent generations, but the two are fundamentally different. Method areas are defined in the JVM specification, while persistent generation is an implementation of the JVM specification, and only in the HotSpot VIRTUAL machine, there is no such term for persistent generation in other virtual machines.

Prior to JDK1.6, the HotSpot virtual machine extended GC generation collection to the method area, or implemented the method area using persistent generation. However, the permanent generation has an upper limit of -xx :MaxPermSize, which is easy to run out of memory.

So in JDK1.7, some of the data is already moved to the Java Heap or Native Heap. For example, static variables of string pools and classes that were in the permanent generation are moved out of the Java Heap and symbolic references are moved to the Native Heap. But the permanent generation still exists, not removed.

In JDK1.8, permanent generation was removed and replaced with a meta-space implementation, which is also an implementation of the method area in the JVM specification. The biggest difference from the permanent generation, however, is that the meta-space is not in the virtual machine, but in local memory. So by default, it is limited only by local memory. The initial space size can be set with the -xx :MetaspaceSize parameter. By default, there is no maximum space limit.

Common OOM and reasons

The OOM in Java is Java. Lang. An OutOfMemoryError. There are mainly the following types:

java.lang.OutOfMemoryError:Java heap space

The Java heap is mainly used to hold various object instances. This exception is thrown when there is not enough space in the heap for new objects, or when the maximum space limit set by the heap is reached.

The main causes of memory overflow are as follows:

  • The number of incoming traffic exceeds the specified heap space.
  • Memory leaks. Objects that cannot be reclaimed consume too much heap space.

java.lang.OutOfMemoryError:Permgen space

In JDK7, the HotSpot VIRTUAL machine implements the method area using persistent generation, which is smaller, less efficient at recycling and prone to memory overflow.

Therefore, JDK8 does away with persistent generation and uses meta-space to implement method areas, which are stored in local memory.

java.lang.OutOfMemoryError:Metaspace

The method area mainly stores the meta information of the class, and the HotSpot metadata area. This exception is thrown when there is not enough space in the meta-space to allocate to the loaded class.

The main reasons for insufficient metadata space are as follows:

  • Loading too many classes is commonjspToo many pages;
  • Meta-space is implemented outside of the heap, mainly due to the memory limitations of the process itself, and is generally difficult to overflow.

The resources

  • Hollis: JVM memory structure VS Java memory model VS Java object model
  • Liuxiaopeng: Java8 Memory Model — PermGen and Metaspace