Write in the front

Here are some questions your interviewer might ask you in the Java memory area. Take out your notebook and jot them down!

Basic questions:

  • Introduce the Java memory area (runtime data area).
  • Java object creation process (5 steps, recommended to be able to write and know what the virtual machine does at each step)
  • Two ways to access and locate objects (handle and direct pointer)

Expansion issues:

  • String class and constant pool
  • Eight basic types of wrapper classes and constant pools


1 Overview (Why learn Java Memory regions)

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.

Some of these components are private to the thread, and others are shared by the thread.

Thread private:

  • Program counter
  • The virtual machine stack
  • Local method stack

Thread shared:

  • The heap
  • Methods area
  • Direct memory

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 known by the compiler (Boolean, byte, CHAR, short, int, float, long, double), object references (reference type, which is different from the object itself, may be a reference pointer to the object’s starting address. It may also point to a handle representing an object or other location associated with this object.

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. Integrate the HotSpot VIRTUAL machine with the Java virtual machine stack.

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 individual threads to store data such as class information that has been loaded by the virtual machine, constants, static variables, code compiled by the just-in-time compiler, and so on. Although the Java Virtual Machine specification describes the method area as a logical part of the Heap, it has an alias called non-heap, which is supposed to distinguish it from the Java Heap.

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 rare in this area, but data is not “permanent” once it 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).

Since the constant pool is part of the method area at runtime and is naturally limited by the method area memory, OutOfMemoryError is thrown when the constant pool can no longer claim memory.

JDK1.7 and later JVMS have moved the runtime constant pool out of the method area, creating an area in the Java Heap to house the runtime constant pool. It also removed the entire permanent generation in JDK 1.8, replacing it with a region called Metaspace

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 (emphasis)

Here is the Java object creation process. I recommend writing it out by ear and knowing what you are doing at each step.

① Class loading check: when a virtual machine receives a new instruction, it first checks whether the parameter of the instruction can locate the symbolic reference of the class in the constant pool, and checks whether the class represented by the symbolic reference has been loaded, parsed, and initialized. If not, the corresponding class loading process must be performed first.

② Allocating memory: After the class load check passes, the virtual machine will allocate memory for the new object. 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.

Two ways to allocate memory :(supplementary content, need to master)

The choice between the two approaches depends on whether the Java heap memory is tidy. Whether the Java heap memory is clean depends on whether the GC collector’s algorithm is “mark-clean” or “mark-tidy” (also known as “mark-compress”). Notably, the copy-algorithm memory is clean as well


Memory allocation concurrency problem

There is a very important issue when creating objects, is thread safety, because in the actual development process, object creation is very frequent things, as a virtual machine, must ensure that thread safety, generally speaking, virtual machines use two ways to ensure thread safety:

  • CAS+ Retry on failure: CAS is an implementation of optimistic locking. Optimistic locking is when an operation is performed each time without locking, assuming no conflicts, and then retry until it succeeds if it fails because of conflicts. The CENTRAL Authentication Service (CAS) configuration fails to retry to ensure atomicity of update operations.
  • TLAB: each thread is allocated a block of memory in Eden area in advance. When THE JVM allocates memory to objects in the thread, it first allocates memory in TLAB. When the object is larger than the remaining memory in TLAB or the memory in TLAB is exhausted, the CAS is used for memory allocation

③ Initialize zero value: After the memory allocation is complete, the VM needs to initialize the allocated memory space to zero value (excluding the object header). This step ensures that the object instance fields can be directly used in Java code without assigning initial values, and the program can access the zero value corresponding to the data type of these fields.

(4) Set the object header: after the initialization of zero value is complete, the VIRTUAL machine must set the object necessary Settings, such as the object is an instance of the class, how to find the metadata information of the class, object hash, object GC generation age and other information. This information is stored in the object header. In addition, the object header can be set differently depending on the running status of the VM, for example, whether biased locking is enabled.

⑤ Execute init method: After all the above work is done, a new object has been created from the perspective of the virtual machine, but from the perspective of the Java program, the object creation has just begun, the

method has not been executed, and all fields are still zero. So, in general, the new instruction is followed by the

method, which initializes the object as the programmer wishes, and a usable object is fully generated.

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 Positioning (key)

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. Handle: If handle is used, a block of memory will be allocated to the Java heap as the handle pool. Reference stores the address of the handle of the object, and the handle contains the specific address information of the instance data and type data of the object.

2. Direct pointer: If direct pointer access is used, then the layout of the Java heap object must consider how to prevent access to the information related to the type of data. 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.

4 Key supplementary content (key)

String class and constant pool

1 There are two ways to create a String:

There is a difference between the two methods of creating objects in the constant pool and creating a new object directly in the heap memory space.

Remember: Whenever you use the new method, you need to create a new object.

2 String constant pools are special. It can be used in two main ways:

  • Strings declared directly in double quotes are stored directly in the constant pool.
  • String. Intern () is a Native method that does this: If the runtime constant pool already contains a String equal to the contents of the String object, a reference to that String from the constant pool is returned; If not, a String with the same contents as this String is created in the constant pool and a reference to the String created in the constant pool is returned.

3 String String stitching



Avoid concatenating multiple strings, as this recreates the object. If you need to change the flower of a string, you can use StringBuilder or StringBuffer.

String s1 = new String(“abc”); How many objects does this sentence create?

Two objects are created.

Validation:

Results:

false
true
Copy the code

Explanation:

The string “ABC” is placed in the constant pool, and then a new copy of the string “ABC” is placed in the Java heap (the string constant “ABC” is determined in the constant pool at compile time, whereas the “ABC” on the Java heap is determined at runtime initialization). Str1 of the Java stack then points to “ABC” on the Java heap.

Eight basic types of wrapper classes and constant pools

  • Most of the basic types of Java wrapper class implements the constant pool technology, namely, Byte, Short, Integer, Long, Character, and Boolean; These five wrapper classes create the corresponding type of cached data for the value [-128,127] by default, but new objects are still created beyond this range.
  • The wrapper class Float,Double, for two floating-point types, does not implement constant pooling technology.

Integer cache source code:

Application Scenarios:

  1. The Integer i1 = 40; I1 = integer.valueof (40); i1= integer.valueof (40); To use objects in the constant pool.
  2. Integer i1 = new Integer(40); New objects will be created in this case, so try to avoid this approach.

Integer is a richer example:

Results:

Explanation:

Statement i4 == i5 + i6, since the + operator does not apply to Integer objects, first i5 and i6 are automatically unboxed, adding the values, i4 == 40. Then the Integer object cannot be directly compared to a numeric value, so i4 automatically unboxes itself to int 40, and finally the statement is converted to 40 == 40 for numeric comparison.