Object memory layout and object access location

Time:2022-1-7

First, feel the memory layout through an example

CustomerTest

public class CustomerTest {
    public static void main(String[] args) {
        Customer cust = new Customer();
    }
}

Customer

Object memory layout and object access location

image.png

Memory layout at this time

Object memory layout and object access location

image.png

notice:

1. Runtime metadata:
There are some information describing the current instance, such as hash value and lock status.
2. Name is the string constant stored in the string constant pool.

Complete memory layout

Object memory layout and object access location

image.png

notice:

n1. Object header
The object header stores the runtime metadata and address pointer (type pointer) of the object
n2. Sample data
The data stored by the object instance, such as its variable information and the variable information inherited from the parent class.
(in fact, the data stored in the object is the variable information stored in the runtime of a business object)

How does the JVM access its internal object instance through the object reference in the stack frame?

Accessed through the reference object in the local variable table in the stack.

Two ways to access objects

1. Access through handle
Instead of directly accessing the object instance, it directly accesses the handle pool.
Handle stores a pointer to an object instance and a pointer to type data.

Object memory layout and object access location

image.png

notice:

handle

Is a variable used by windows to manage virtual addresses.
Baidu Encyclopedia explains:
A handle is an identifier used to identify an object or item. It can be used to describe forms, files, etc. it is worth noting that a handle cannot be a constant [1]
The reason why windows wants to set up a handle is fundamentally due to the problem of memory management mechanism, that is, virtual address. In short, the address of the data needs to be changed. After the change, someone needs to record and manage the change. Therefore, the system uses a handle to record the change of the data address. In programming, handle is a special smart pointer. When an application wants to refer to memory blocks or objects managed by other systems (such as database and operating system), it needs to use handle

2. Direct pointer

Directly access the object instance in the heap, and the object instance points to the type pointer of the method area

Object memory layout and object access location

image.png

Comparison between the two

Through handle access, a memory empty storage handle needs to be specially opened up in the virtual machine.
At this time, the object search process is:
Object finds the handle in the heap by reference, and then finds the object instance by variables in the handle. The process of finding a handle is one more step than direct access to the middle. Naturally, there is no direct pointer to achieve high efficiency.

Advantages of direct access:

1. There is no need to open up a special memory space to store handles. (space)
2. The object search process is efficient. It saves time to find the handle than handle access. (time)
It can be seen that direct access has advantages in space and time. This is also the method adopted by hotspot. Therefore, in the previous object layout, the cust object directly points to the instance object in the heap, and the type pointer method area in the instance object header.

Advantages of handle access:

The performance is stable. It adds a layer to the reference and object instance. The reference always only points to the handle. The disadvantage of direct access is that once the object instance moves, the pointer of the reference will change accordingly.

Recommended Today

Proper memory alignment in go language

problem type Part1 struct { a bool b int32 c int8 d int64 e byte } Before we start, I want you to calculatePart1What is the total occupancy size? func main() { fmt.Printf(“bool size: %d\n”, unsafe.Sizeof(bool(true))) fmt.Printf(“int32 size: %d\n”, unsafe.Sizeof(int32(0))) fmt.Printf(“int8 size: %d\n”, unsafe.Sizeof(int8(0))) fmt.Printf(“int64 size: %d\n”, unsafe.Sizeof(int64(0))) fmt.Printf(“byte size: %d\n”, unsafe.Sizeof(byte(0))) fmt.Printf(“string size: %d\n”, […]