Memory management is a basic skill developers must master, otherwise programs will always crash with all kinds of elusive errors. Some languages, such as C and C++, have developers who apply for memory and free it when they use it, but poor code writing habits often result in memory leaks, referencing null Pointers, and other errors. Java with the help of virtual machines to help us complete a lot of work, so that developers from the deep pit of memory management to climb out, but because of the layer of virtual machines, problems when the response strategy is more effective, need to understand the virtual machine memory management mechanism.

This article is only a superficial introduction to the virtual machine memory area of the general distribution, so that beginners have a general impression in their mind, and the impression of the beginning with the following picture:

Java memory regions are divided into two large regions, one shared by threads and the other unique to each thread. When I first learned about programming, I had the impression that the stack memory was in the body of the method, that all the variables defined were in the stack memory, that the method ended up being empty, and that the heap memory was allocated using the new keyword. Of course, this is just the idea of the thick line. The following is the memory distribution shown in the figure above.

Program counter

It is similar to the PC register in the CPU, which is used to store the address of the next instruction, but instead of using the CPU’s program counter, the virtual machine creates an area of memory that simulates the CPU’s program counter. Changing the value of the counter to select the next bytecode instruction to execute, including branches, loops, jumps, exceptions, thread recovery and other basic functions depend on the counter.

Each thread in Java has its own separate counters, which do not affect each other, so that when multithreading, a suspended thread can recover from the counter and continue execution. So program counters are also thread isolated. When Java methods are executed, the counter stores the address of the VIRTUAL machine bytecode. When Native methods are executed, the counter is empty (undefined). This region does not generate OutOfMemoryError.

The virtual machine stack

The Java virtual machine stack is also thread-private, with a lifecycle equivalent to that of a thread. The virtual machine stack describes the memory model in which Java methods are executed. When a method is executed, a stack frame is created to store the data structures used during the execution of the method, including local variable tables, operand stacks, dynamic links, method exits, and so on.

When a method executes, a stack frame containing the above elements is pushed onto the stack, and when the method exits, the stack frame is pushed off the stack. We all know that memory is divided into heap area and stack area, which is actually a crude division, stack refers to the virtual machine stack, and the most important part of the local variable table.

The Java garbage collector does not reclaim the contents of the stack because the contents of the stack are automatically freed at the end of the method. The local variable table contains various basic data types, object references, and returnAddresses known at compile time. Basic data types are Java’s eight basic data types (Boolean,byte,char, Short, int, float, Long, double), object references, which you can think of as Pointers to the actual object address or as a handle to an object, ReturnAddress is the address of a bytecode instruction. When entering a method, the amount of space it needs to allocate is known at compile time.

The following two exceptions may be reported in the vm stack:

  • StackOverflowError: The stack depth requested by the thread is greater than the allowed depth
  • OutOfMemoryError: Most virtual stacks are dynamically extensible and will be thrown if sufficient memory cannot be allocated.

Local method stack

Different from a virtual machine stack implementation is a Java method, local stack is a virtual machine to use Native methods of service, we were looking at some of the library when the source location at the end of the normal method is to use Native implementation, but in the virtual machine specification for local method of using the language, to use hard and fast rules in the form of so the virtual machine can achieve it. The local method stack and virtual machine stack are combined in HotSpot.

The heap

We’ve heard of the malloc method allocating space on the heap at least since we learned C. The Java heap also allocates instance objects. In the virtual machine specification, basically all object instances and arrays are allocated on the heap, such as objects referred to by object references on the stack. However, with the development of compiler technology, it is not so pure that all objects are allocated on the heap.

The heap is also the main site for garbage collection (GC). Modern collectors basically use generational collection algorithms, so the heap can also be divided into new generation and old generation, and more detailed, there are Eden space, From Survivor space and To Survivor space. Because the virtual machine implements automatic garbage collection, new objects in the heap do not need to be released manually in Java.

We can control the default size of the heap with -xmx and -xms, and throw an OutOfMemoryError if there is no more memory in the heap.

Methods area

The method area is also shared between threads, typically storing loaded class information, constants, static variables, code compiled by the just-in-time compiler, and so on. In general, many people also refer to method regions as permanent generations. It’s just that the HotSpot team has extended GC generation collection to the method area as well, allowing the garbage collector to reclaim the memory in the method area, but other virtual machine implementations don’t do this, there are no persistent generations, and HotSpot itself has removed constant pools from the persistent generation in JDK1.7.

Garbage collection is relatively absent from the methods area. This area mainly collects constant pools and type offloads, but in practice the conditions for both collections are extremely stringent and collections rarely occur.

The runtime constant pool is part of the method area, and the Class file contains the constant pool information for the various literals and symbolic references generated at compile time that go into the runtime constant pool of the method area after the Class is loaded. Refer to my: Understanding the JVM class file format in depth for this section