Write in the front
Basic questions:
- Introducing 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
Java programmers must see documentation
Ha ha skin once! I open source a Java study guide document myself. A cover most Java programmers need to master the core knowledge, is gradually improved step by step, looking forward to your participation. Github address: github.com/Snailclimb/… . Take a look, I think you will not regret, if possible, you can give a Star encouragement!
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.
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
Recommended reading: Differentiating constant pools in Java: blog.csdn.net/qq_26222859…
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
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 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:
-
Handle: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.
- Direct Pointers: 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 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.
Key supplementary content
String class and constant pool
1 There are two ways to create a String:
String str1 = "abcd"; String str2 = new String("abcd"); System.out.println(str1==str2); //falseCopy the code
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.
String s1 = new String(" computer "); String s2 = s1.intern(); String s3 = "computer "; System.out.println(s2); // system.out. println(s1 == s2); //false because one is a String in the heap and the other is a String in the constant pool, system.out.println (s3 == s2); //true, because both are String pairs in the constant poolCopy the code
3 String String stitching
String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing"; String str4 = str1 + str2; // Create a new object on the heap String str5 = "String "; System.out.println(str3 == str4); //false System.out.println(str3 == str5); //true System.out.println(str4 == str5); //falseCopy the code
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:
String s1 = new String("abc"); String s2 = "ABC "; System.out.println(s1 == s2); // Print false because one is heap memory and the other is constant pool memory, so the two are different. System.out.println(s1.equals(s2)); / / output trueCopy the code
Results:
false
trueCopy 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 i1 = 33; Integer i2 = 33; System.out.println(i1 == i2); // Output true Integer i11 = 333; Integer i22 = 333; System.out.println(i11 == i22); // print false Double i3 = 1.2; Double i2 = 1.2; System.out.println(i3 == i4); / / output is falseCopy the code
Integer cache source code:
/** * This method will always cache values in the range -128 to 127, including endpoints, and can cache other values outside this range. */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }Copy the code
Application Scenarios:
- The Integer i1 = 40; I1 = integer.valueof (40); i1= integer.valueof (40); To use objects in the constant pool.
- Integer i1 = new Integer(40); In this case, a new object is created.
Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1==i2); / / output is falseCopy the code
Integer is a richer example:
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1=i2 " + (i1 == i2));
System.out.println("i1=i2+i3 " + (i1 == i2 + i3));
System.out.println("i1=i4 " + (i1 == i4));
System.out.println("i4=i5 " + (i4 == i5));
System.out.println("i4=i5+i6 " + (i4 == i5 + i6));
System.out.println("40=i5+i6 " + (40 == i5 + i6)); Copy the code
Results:
i1=i2 true
i1=i2+i3 true
i1=i4 false
i4=i5 false
i4=i5+i6 true
40=i5+i6 trueCopy the code
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.
Write in the last
Open Source Document Recommendation
Java-guide: a Guide that covers the core knowledge most Java programmers need to master. It is being improved step by step. We look forward to your participation.
Github address: github.com/Snailclimb/…
Reference:
- Understanding the Java Virtual Machine in Depth: Advanced JVM Features and Best Practices (2nd Edition)
- Real Java Virtual Machine
- www.cnblogs.com/CZDblog/p/5…
- www.cnblogs.com/java-zhao/p…
- Blog.csdn.net/qq_26222859…
- Blog.csdn.net/cugwuhan201…