In-depth Understanding of the Java Virtual Machine: Advanced JVM Features and Best Practices (2nd edition)

This section often meet questions:

Introduce the Java memory area (runtime data area).

Object access location in two ways.

1 overview

For Java programmers, under the automatic memory management mechanism of virtual machines, there is no need to write the corresponding DELETE /free operation for a new operation like C/C++ program developers, which is not prone to memory leakage and overflow problems. Because Java programmers have entrusted memory control to the Java virtual machine, memory leaks and spills can be a daunting task if you don’t know how the virtual machine is using memory.

2 Run time data area

During the execution of Java programs, the Java VIRTUAL machine divides the memory it manages into different data areas.

2.1 Program counter

A program counter is a small memory space that can be viewed as a line number indicator of the bytecode being executed by the current thread. The bytecode interpreter works by changing the value of this counter to select the next bytecode instruction to be executed. Branches, loops, jumps, exception handling, thread recovery and other functions rely on this counter to complete.

In addition, in order to restore the thread to the correct execution position after switching, each thread needs to have an independent program counter, which does not affect each other and is stored independently. We call this kind of memory area “thread private” memory.

2.2 Java Virtual Machine Stack

Like program counters, the Java virtual machine stack is thread-private and has the same lifecycle as a thread, describing an in-memory model of the execution of Java methods.

Java memory can be roughly divided into Heap memory and Stack memory, where the Stack is now referred to as the virtual machine Stack, or the local variable scale part of the virtual machine Stack.

The local variable table mainly stores various data types and object references known by the compiler.

2.3 Local method stack

This function is very similar to that of the virtual machine stack, except that the virtual machine stack performs Java methods (that is, bytecode) services for the virtual machine, while the Native method stack serves Native methods used by the virtual machine.

2.4 the heap

The largest chunk of memory managed by a Java virtual machine, the Java heap is an area of memory shared by all threads and created when the virtual machine is started. The sole purpose of this memory area is to hold object instances, and almost all object instances and arrays are allocated memory here. The Java Heap is the primary area managed by the Garbage collector and is therefore also known as the Garbage Collected Heap. From the point of view of garbage collection, the Java heap can be subdivided into: new generation and old generation: Eden space, From Survivor, To Survivor space, and so on, since collectors are basically generational garbage collection algorithms. The purpose of further partitioning is to better reclaim memory, or to allocate memory faster.

2.5 method area

The method area, like the Java heap, is an area of memory shared by threads to store data such as class information that has been loaded by the virtual machine, constants, static variables, and even compiled code by the compiler.

The method area in the HotSpot VIRTUAL machine is also often referred to as a “persistent generation”, and the two are not essentially equivalent. It’s just that the HotSpot VIRTUAL machine design team implements the method area with persistent generations so that the HotSpot VIRTUAL machine garbage collector can manage this part of memory as well as the Java heap. This is not a good idea, however, because it is more likely to run into memory overflow problems. Garbage collection is relatively present in this area, but not “permanent” once the data enters the method area.

2.6 Runtime constant pool

The runtime constant pool is part of the method area. In addition to the description of the Class version, fields, methods, interfaces, etc., the Class file also contains constant pool information (used to store various literal and symbolic references generated at compile time).

2.7 Direct Memory

Direct memory is not part of the virtual machine’s run-time data area, nor is it defined in the virtual machine specification, but it is frequently used. It may also cause an OutOfMemoryError to occur.

The NIO(New Input/Output) class added in JDK1.4 introduces an I/O mode based on Channel and Buffer, which can directly allocate out-of-heap memory using Native function library. It then operates through a DirectByteBuffer object stored in the Java heap as a reference to this memory. This can significantly improve performance in some scenarios because it avoids copying data back and forth between the Java heap and Native heap.

Native direct memory allocation is not limited by the Java heap, but since it is memory, it is limited by the total native memory size and processor addressing space.

3 HotSpot VM object exploration

With the introduction above we have a general idea of the virtual machine memory, let’s take a detailed look at the HotSpot VIRTUAL machine in the Java heap object allocation, layout and access process.

3.1 Object Creation

When a virtual machine arrives at a new instruction, it first checks to see if the instruction’s arguments locate the symbolic reference to the class in the constant pool, and to see if the symbolic reference represents a class that has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.

After the class load check passes, the virtual machine next allocates memory for the new objects. The size of memory required by an object is determined after the class is loaded, and the task of allocating space for an object is equivalent to dividing a certain size of memory from the Java heap. There are two types of allocation: “pointer collision” and “free list”, which allocation is determined by whether the Java heap is clean, which in turn is determined by whether the garbage collector used has collation capabilities.

The CENTRAL Authentication Service (CAS) configuration fails to retry to ensure atomicity of update operations.

Next, the virtual machine sets up the object as necessary, such as which class the object is an instance of, how to find the metadata information about the class, the object’s hash, the object’s GC generation age, and so on. This information is stored in the object header. The object header can be set differently depending on the VM running status, for example, whether biased locking is enabled. After the new instruction is executed, init is executed as the programmer wishes and a usable object is created.

3.2 Memory layout of objects

In the Hotspot VIRTUAL machine, the layout of objects in memory can be divided into three fast areas: object headers, instance data, and alignment padding.

Hotspot virtual machine object consists of two pieces of information, the first part of its own runtime data are used to store objects (hash, GC generational age, lock status flag, etc.), the other part is a pointer type, namely the object pointer to its class metadata, virtual machine this object is determined by the pointer to the instance of the class.

The instance data part is the valid information that the object actually stores and the content of various types of fields defined in the program.

The alignment padding part is not necessarily there and has no special meaning. It just serves as a placeholder. Because the Hotspot VIRTUAL machine’s automatic memory management system requires that the object’s starting address be an integer multiple of 8 bytes, in other words, the object’s size must be an integer multiple of 8 bytes. The object header is exactly a multiple (1 or 2) of 8 bytes, so when the object instance data part is not aligned, it needs to be filled by alignment.

3.3 Object Access Location

Objects are created to use objects, and our Java program operates on specific objects on the heap using reference data on the stack. The object access mode depends on the IMPLEMENTATION of the VM. Currently, the mainstream access mode includes ① handle and ② direct pointer:

  1. If the handle is used, a chunk of memory will be allocated to the Java heap as the handle pool. Reference stores the handle address of the object, and the handle contains the specific address information of the instance data and type data of the object.

  2. If direct pointer access is used, then the layout of the Java heap object must consider how to prevent access to information about the type data, and the direct stored in reference is the address of the object.

Both object access methods have their own advantages. The biggest benefit of using handles for access is that reference stores a stable handle address and only changes the instance data pointer in the handle when the object is moved. Reference itself does not need to be modified. The biggest advantage of using direct pointer access is fast speed, it saves the time cost of a pointer location.

Welcome to my wechat official account :”Java Interview Clearance Manual “(a warm wechat official account, looking forward to common progress with you ~~~ adhere to the original, share beautiful articles, share a variety of Java learning resources) :