1, Instantiation of objects
Large factory interview questions
Meituan:
- How are objects stored in the JVM?
- What is in the object header information?
Ant gold suit:
Second side: what's in the java object header
1.1 object creation method
- new: the most common way, the static class method of calling getInstance in singleton class, and the static method of XXXFactory.
- Class's newInstance method: it is marked as obsolete in JDK9, because it can only call the null parameter constructor, and the permission must be public
- Constructor's newInstance(Xxxx): reflection mode. You can call null or parameterized constructors
- Use clone(): do not call any constructor. The current class needs to implement the clone method in the clonable interface
- Use serialization: get the binary stream of an object from the file from the network. Serialization is generally used for network transmission of sockets
- Third party library Objenesis
To create an object
Viewing the creation process of objects from bytecode
public class ObjectTest { public static void main(String[] args) { Object obj = new Object(); } }
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=2, args_size=1 0: new #2 // class java/lang/Object 3: dup 4: invokespecial #1 // Method java/lang/Object."<init>":()V 7: astore_1 8: return LineNumberTable: line 9: 0 line 10: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String; 8 1 1 obj Ljava/lang/Object; }
1. Judge whether the class corresponding to the object is loaded, linked and initialized
- When the virtual machine encounters a new instruction, first check whether the parameters of the instruction can locate the symbol reference of a class in the constant pool of Metaspace, and check whether the class represented by the symbol reference has been loaded, parsed and initialized. (that is, judge whether class meta information exists).
- If the class is not loaded, use the current class loader to find the corresponding one with ClassLoader + package name + class name as key in the parent delegation mode Class file. If the file is not found, a ClassNotFoundException exception will be thrown. If it is found, the class will be loaded and the corresponding class object will be generated.
2. Allocate memory for objects
- First, calculate the size of the space occupied by the object, and then divide a piece of memory in the heap for the new object. If the instance member variable is a reference variable, only the reference variable space can be allocated, that is, 4 bytes
- If the memory is regular: allocate memory by pointer collision
- If the memory is regular, the virtual machine will use the Bump The Point method to allocate memory for the object.
- It means that all used memory is on one side, free memory is on the other side, and a pointer is placed in the middle as the indicator of the dividing point. Allocating memory is just moving the pointer to the free memory for a distance equal to the size of the object.
- If the garbage collector selects Serial, ParNew, which is based on the compression algorithm, the virtual machine adopts this allocation method. Generally, when using a collector with a Compact process, pointer collision is used.
- The memory is defragmented and the other side is marked as free
- If the memory is irregular
- If the memory is not regular and the used memory and unused memory are staggered, the virtual machine will use the free list to allocate memory for the object.
- It means that the virtual machine maintains a list, which memory blocks are available. When reallocating, find a large enough space from the list to divide it into object instances, and update the contents on the list. This allocation method is called "Free List"
- Which allocation method to choose is determined by whether the Java heap is regular or not, and whether the Java heap is regular or not is determined by whether the garbage collector used has compression and sorting function
- There will be many memory fragments in the heap memory cleaned up by the mark clearing algorithm.
3. Handling concurrency issues
- CAS + failure retry is adopted to ensure the atomicity of updates
- Each thread is pre allocated TLAB - set by setting the - XX:+UseTLAB parameter (regional locking mechanism)
- Each thread is assigned an area in the Eden area
4. Initialize allocated space
-
Set default values for all attributes to ensure that the object instance field can be used directly without assignment
-
Order of assigning values to object properties:
- Property is initialized by default
- Display initialization / code block initialization (side-by-side relationship, who comes first depends on the order of code writing)
- constructor initialization
5. Set the object header of the object
The class to which the object belongs (that is, the metadata information of the class), the HashCode of the object, the GC information and lock information of the object are stored in the object header of the object. How this process is set up depends on the JVM implementation.
6. Execute the init method for initialization
- From the perspective of Java program, initialization begins formally. Initialize the member variable, execute the instantiated code block, call the construction method of the class, and assign the first address of the object in the heap to the reference variable
- Therefore, generally speaking (determined by the invokespecial instruction followed in the bytecode), the new instruction will then execute the init method to initialize the object according to the programmer's wishes, so that a truly available object can be created.
init method from the perspective of bytecode
/** * Test object instantiation process * ① Load class meta information - ② allocate memory for objects - ③ handle concurrency problems - ④ default initialization of attributes (zero initialization) * - ⑤ Set the information of object header - ⑥ explicit initialization of attribute, initialization in code block and initialization in constructor * * * To assign a value to an object's attribute: * ① Default initialization of attributes - ② explicit initialization / ③ initialization in code block - ④ initialization in constructor */ public class Customer{ int id = 1001; String name; Account acct; { name = "Anonymous customer"; } public Customer(){ acct = new Account(); } } class Account{ }
Bytecode of Customer class
0 aload_0 1 invokespecial #1 <java/lang/Object.<init>> 4 aload_0 5 sipush 1001 8 putfield #2 <com/atguigu/java/Customer.id> 11 aload_0 12 ldc #3 < anonymous customer > 14 putfield #4 <com/atguigu/java/Customer.name> 17 aload_0 18 new #5 <com/atguigu/java/Account> 21 dup 22 invokespecial #6 <com/atguigu/java/Account.<init>> 25 putfield #7 <com/atguigu/java/Customer.acct> 28 return
- Bytecode instruction of init() method:
- Default initialization value of attribute: id = 1001;
- Display initialization / code block initialization: name = "anonymous customer";
- Constructor initialization: acct = new Account();
2, Object's memory layout
Memory layout summary
public class Customer{ int id = 1001; String name; Account acct; { name = "Anonymous customer"; } public Customer(){ acct = new Account(); } public static void main(String[] args) { Customer cust = new Customer(); } } class Account{ }
Graphic memory layout
3, Object access location
How does the JVM access its internal object instance through the object reference in the stack frame?
Location, accessed through reference on the stack
There are two ways to access objects: handle access and direct pointer
1. Handle access
- Disadvantages: a space is opened up in the heap space as a handle pool, and the handle pool itself will also occupy space; The objects in the heap can only be accessed through two pointer accesses, which is inefficient
- Advantages: the reference stores a stable handle address. When the object is moved (it is common to move objects during garbage collection), it will only change the instance data pointer in the handle. The reference itself does not need to be modified
2. Direct pointer (adopted by HotSpot)
- Advantages: the direct pointer is a reference in the local variable table, which directly points to the instance in the heap. There is a type pointer in the object instance, which points to the object type data in the method area
- Disadvantages: when an object is moved (it is common to move objects during garbage collection), the value of reference needs to be modified