According to the Java Virtual Machine Specification, the Java VIRTUAL machine manages a total of five memory areas, which belong to two categories: “thread isolated area” and “thread shared area”.

1. Thread isolation area

Refers to an area of memory that is owned by all threads and does not affect each other.

1.1 Program counter

Store the line number of the bytecode executed by the current thread, which is the basic guarantee for the program to realize the control flow (loop, branch, jump, etc.).

If the current thread executes a Native method, the value of the program counter is null.

This area of memory does not throw an OutOfMemoryError.

1.2 VM Stack

Its life cycle is consistent with that of threads and is an in-memory model describing method execution.

When each method is executed, the corresponding stack frame is created in the virtual machine stack, and the process from the call to the end of the execution corresponds to the push and exit of the stack frame.

An area of the stack frame called the local variable table is used to store basic data types known at compile time, object references, or ReturnAdress (references to bytecode instructions). The storage space is divided into slots. The 64-bit double and long types take up space in two slots, and the other types take up space in one slot.

When entering a method, the number of slots that need to be allocated is something that can be determined after compilation and does not change at run time.

Virtual machine stack errors occur in one of two situations:

  • The depth of the VM stack exceedsJVMThe maximum depth that can be allowedStackOverflowError;
  • Is generated when sufficient memory cannot be allocated for creating a VM stackOutOfMemoryError;

1.3 Local method stack

Its function is basically the same as the virtual machine stack, except that its service objects are Java native methods.

Some VMS combine the virtual machine stack and local method stack at the implementation level (for example, hot-spot VMS).

2. Thread sharing area

All threads share the memory areas used.

2.1 the heap

As defined in the Java Virtual Machine Specification, all object instances and arrays should be allocated on the heap.

Heap memory is also an area managed by the garbage collector. Since modern garbage collectors are basically designed according to the theory of generational collection, it is often thought that there are “new Generation”, “old age”, “Eden zone “, “Survior zone “and other concepts in the heap memory. This perception is false. These concepts belong to the garbage collector, not the heap itself.

Supplementary concept: In order to improve the efficiency of object allocation, the heap memory may be divided into multiple Thread private Allocate Buffer, known as Thread Local Allocate Buffer, TLAB. However, this is an implementation level optimization of the virtual machine and does not change the fact that the heap memory is shared by all threads.

Almost all modern virtual machines support an “extensible heap” design (set by the -xms and -xmx parameters). An OutOfMemoryError is generated when there is not enough memory allocated for an instance and the heap memory cannot grow any further.

2.2 method area

Store type variables, constants, static variables, just-in-time compile code caches, and more.

In early implementations of hot-spot virtual machines, the garbage collection generational design was extended to the method area, which was implemented in a “permanent” manner, hence the term “permanent generation”. After Java8, the “permanent generation” was abolished and the method area was implemented as a “meta-space”.

The runtime constant area is the part of the method area used to store the constant pool of class files after the class has been loaded.

Note: Refer to Chapter 6 for information about class file constant pools

An OutOfMemoryError will be generated when the method area cannot meet the new memory allocation requirements.

3. Direct memory

With the introduction of NIO in Java1.4, there was a way to use DirectByteBuffer to manipulate out-of-heap memory (direct memory).

The allocation of direct memory is not limited by the JVM, but is certainly affected by the server’s own memory.

If the direct memory usage is too large, the available memory of the JVM may be too small, and OutOfMemoryError is easily generated when the server memory remains unchanged.