preface

In the Learning JVM series, you’ve covered the JVM specification, the Class file format, and how to read bytecode, ASM bytecode processing, the life cycle of a Class, and custom Class loaders. In this article, we will learn about memory allocation. This knowledge is useful for understanding Java execution processes such as Person Person = new Person(), a simple line of code that contains data stored in memory.

If you’re interested in JVMS, bytecodes, Class file formats, ASM bytecode processing, Class loading, and custom Class loaders, you’ll find out more

Android engineers learn about JVMS (4)- class loading, connecting, initialization, and unloading

Android engineers learn how to use THE JVM(iii)- bytecode framework ASM

Android Engineer learning JVM(II)- Teaches you to read Java bytecode

Android Engineers learn about JVM(I)- Overview of the JVM

JVM simplifies architecture

Looking back at the overall architecture of the JVM, the first step is to load the bytecode files (class files) into memory through the class loader, and then execute the corresponding instructions through the execution engine, which has a series of interactions with memory. The execution engine then interacts with the computer’s local library interface to achieve the final effect.

In the previous article, you saw that the classloader ultimately reads the bytecode file as a binary stream and loads it into memory. Let’s take a look at the run-time data section.

2. Runtime data area

The runtime data area includes: PC register, Java virtual machine stack, local method stack, Java heap, method area, runtime constant pool, etc

Let’s introduce them one by one.

2.1 brief introduction to runtime data area

PC register:

1. Each thread has a PC register, which is private to the thread and stores the address pointing to the next instruction

2, when creating the thread, create the corresponding PC register

3. When executing the local method, the VALUE of the PC register is undefined

4, PC register is a small memory space, is not OutOfMemoryError memory area

Java stack:

A stack consists of a series of frames (also known as a Frame stack in Java) that are thread private

Frames are used to hold a method’s local variables, operand stack, constant pool Pointers, dynamic links, method return values, and so on

Each method call creates a frame and presses it. When exiting the method, changing the top of the stack pointer destroys the memory in the stack frame

The local variable table holds various basic data types and reference types known at compile time. Each slot holds 32 bits of data, with longs and doubles in two slots

Stack advantage: access faster than the heap, second only to registers

Disadvantages of stack: the size and lifetime of data in the stack are determined at compile time and lack of flexibility

The Java heap:

Used to store objects and arrays created by the application system, which are shared by threads

Heap priority: Memory size is dynamically allocated at runtime and garbage collection is automatically performed

Disadvantages of heap: Relatively slow efficiency

Methods area:

Usually used to hold the structure information of loaded classes, which is shared by threads

Runtime constant pool (method area allocation) :

Is a constant pool table for each Class or interface in a Class file, which is represented at runtime, usually including: Class version, field, method, interface, etc

Local method stack:

The stack used in the JVM to support native method execution is the native method stack

2.2 Interaction between stack, heap and method area

For example, User User = new User(). Contains user object references, user object instance data, and user class definitions. These three are stored in stack, heap and method area respectively.

In the previous article, we saw that stacks are thread private, whereas heap and method areas are thread shared. In multithreading, different threads can create multiple user object references to the same object in the heap, sharing data.

There can be multiple User instance objects in the heap, and the metadata information of each User instance object is the same. Only the reference of metadata information is kept, and the class definition, method, and field are put in the method area. This allows each instance object to share class definition, method, and field information.

Therefore, this design greatly saves data space.

Java heap memory model and allocation

From the above, we learned that only the heap is dynamically allocated at runtime. The following will be introduced from the structure of the heap and the memory layout of the objects

3.1 Overview of Java heap memory

The Java heap is used to store objects and arrays created by the application system and is shared by all threads

2. The Java heap allocates memory dynamically at run time, automatically collecting garbage

3.2 Memory structure of the Java heap

The Java heap is generational, divided into new generation and old generation

Cenozoic: divided into Eden region and survival region. The Eden area stores newly created objects. The Eden area can be divided into the From area and To area. Objects from the new generation that are not recycled through garbage collection are copied to the old age

Old age: Storage objects are much older than the new generation storage objects and store some large objects

Here are two notable formulas:

1. Total heap size = New generation + old age

2. Cenozoic =Eden + Survival zone

3.3 memory layout of objects

The layout of objects stored in memory (using the HotSpot VIRTUAL machine as an example) is divided into object headers, instance data, and aligned padding

The object header contains two parts:

1. Mark Word: Stores the running data of the object itself, such as HashCode, GC generation age, lock status, etc

2. Type pointer: a pointer to an object’s class metadata

Instance data:

Where the actual object instance data is stored

Align fill:

Just a placeholder, no special meaning (HotSpot virtual machine requires that the object start address be a multiple of 8 bytes, if not aligned)

4. Object access positioning

In Section 3 we talked about how instance objects are stored in the heap, and in Section 2.2 we introduced the interaction between stack and heap. This section explains how to find object instance data in the heap from the stack.

The way objects are accessed is not specified in the JVM specification. Currently, there are two main implementations, one is to use a handle, the other is to use a pointer

4.1. Use handle positioning

In this way, a block of memory will be allocated in the Java heap as the handle pool, and the address of the handle will be stored in the reference, and the address of the instance data and class metadata of the object will be stored in the handle, as shown in the following figure:

In the Java stack local variable table, reference refers to an object pointer (including instance data and type data Pointers) to the handle pool in the Java heap, which in turn points to object instance data, and object type data to object type data in the method area

4.2. Use Pointers to locate

In the Java stack local variable table, the reference reference refers to the region of the instance data in the Java heap (which also has Pointers to the object type data).

4.3 Advantages and disadvantages of handle positioning and pointer positioning

Handle positioning: The advantage is that when the object instance changes, the object instance data pointer in the handle pool is modified, while reference does not need to be modified, and is an indirect reference. The disadvantage is slower speed, because it is indirect positioning

Using pointer positioning: advantage is faster, less than using a handle positioning index. However, reference needs to change when the object instance changes

5, summary

1. Brief introduction to the simplified structure of the Jvm, understanding the relationship between memory regions and classloaders, execution engines, garbage collectors, and so on

2. Focus on runtime data partitioning and the role of each part. The PC register, stack, local method stack are thread private, method area and heap are thread shared

3. This section describes the location and interaction of object reference, instance data, and object type data when creating objects

4. Introduce heap memory structure, briefly explain the new generation and the old generation (this section will focus on garbage collection later), introduce an object instance in heap memory to store object headers, instance data, and possibly data alignment. The object header holds a pointer to the instance type data

5. Finally, it introduces the common positioning methods of objects, including handle positioning and pointer positioning, as well as the differences between these two methods. HotSpot uses pointer positioning