In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-20 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail how to use JVM source code to analyze the creation process of Java objects, the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
Based on the implementation of HotSpot, the creation process of Java object is analyzed deeply.
Define two simple classes AAA and BBB
View the compiled bytecode through "javap-c AAA" `, as follows:
The new keyword in Java corresponds to the new instruction in jvm, which is defined in the InterpreterRuntime class and implemented as follows:
The implementation process of new instruction:
1. Where pool is the constant pool of AAA, and the class of AAA has been loaded into the virtual machine. The # 2 after the new instruction indicates that the symbol reference of the fully qualified name of the BBB class is in the location of the constant pool.
2. The method pool- > klass_at is responsible for returning the klassOop object corresponding to BBB, which is implemented as follows:
If the data at the specified location (# 2) in the constant pool is already of oop type, indicating that the class of BBB has been loaded and parsed, return klassOop; directly through (klassOop) entry.get_oop (). Otherwise, if you use BBB * * times, you need to parse the symbolic reference of BBB, load the class class of BBB, generate the corresponding instanceKlass object, and update the symbolic reference of the corresponding location in constant pool.
3. Klass- > check_valid_for_instantiation can prevent abstract classes from being instantiated
4. Klass- > initialize is implemented as follows:
If the instanceKlass object of BBB has been initialized, return it directly; otherwise, initialize it through the initialize_impl method, and the entire initialization algorithm is divided into 11 steps, as shown below:
Step1
Lock before initialization through ObjectLocker to prevent multiple threads from initializing concurrently.
Step2
If the current instanceKlass is in the being_initialized state and is being initialized by another thread, the execution ol.waitUninterruptibly waits for notification after the other thread finishes.
Step3
If the current instanceKlass is in the being_initialized state and is initialized by the current thread, it returns directly.
In fact, I have a question about the handling of this step. What kind of situation will come to this? After being greatly reminded by RednaxelaFX, step3 will be executed in the following cases:
For example, class A has static variables pointing to a new class B instance, and class B has static variables pointing to new class An instances, so class An is initialized when An is used externally, class B initialization is triggered during the initialization process, and class B initialization triggers class An initialization again.
Step4
If the current instanceKlass is in fully_initialized state, which means that the initialization has been completed, return directly
Step5
If the current instanceKlass is in initialization_error state, initialization failed and an exception is thrown.
Step6
Sets the status of the current instanceKlass to being_initialized; sets the initialization thread to the current thread.
If the current instanceKlass is not an interface type and the parent class is not empty and has not been initialized, initialization of the parent class is performed.
Step8
Execute the static block code through the this_oop- > call_class_initializer method, which is as follows:
This_oop- > class_initializer () can get the static code block entry, and finally execute the code block logic through JavaCalls::call, and then the next layer is the implementation of the specific operating system.
Step9
If there is no exception in the initialization process, indicating that the instanceKlass object has been initially completed, set the status of the current instanceKlass to fully_initialized,*** to notify other threads that initialization has been completed; otherwise, execute step10 and 11.
Step10 and 11
If an exception occurs in initialization, the status of the current instanceKlass is set to initialization_error, and other threads are notified of an exception in initialization.
5. If instanceKlass initialization is complete, klass- > allocate_instance will create an instanceOopDesc object in heap memory, that is, instantiation of the class.
InstanceOopDesc
When you new an object in Java, you essentially create an instanceOopDesc object in heap memory.
InstanceOopDesc inherits from oopDesc in implementation, where oopDesc is defined as follows:
Of course, this is only part of the implementation of oopDesc, which contains two data members: _ mark and _ metadata.
1. _ mark is an object of type markOop, which is used to store the runtime data of the object itself, such as hash code (HashCode), GC generational age, lock status flag, lock held by thread, biased thread ID, biased timestamp, etc., which takes up the same amount of memory as the virtual machine bit length. A more specific implementation can read "HotSpot implementation Analysis of java object header".
2. _ metadata is a union, where both wideKlassOop and narrowOop are pointers to InstanceKlass objects, wide is a normal pointer, and narrow is a compressed class pointer (compressed Class pointer)
The process of creating an instanceOopDesc object
InstanceOopDesc objects are created through instanceKlass::allocate_instance, and the implementation process is as follows:
1. Has_finalizer determines whether the current class contains finalize methods that are not empty.
2. Size_helper determines how much memory needs to be allocated to create the current object
3. CollectedHeap::obj_allocate requests a specified amount of memory from the heap, and creates an instanceOopDesc object, which is implemented as follows:
4. If the current class overrides the finalize method and is not empty, the generated object needs to be encapsulated as a Finalizer object and added to the Finalizer linked list. When the object is GC, if it is a Finalizer object, the object will be assigned to the pending object. The Reference Handler thread push the pending object into the queue, and the Finalizer thread poll to the object, first delete the corresponding object in the Finalizer linked list, and then execute the object's finalize method
On how to use JVM source code to analyze the Java object creation process is shared here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.