中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用JVM源碼分析Java對象的創建過程

發布時間:2021-10-23 17:28:40 來源:億速云 閱讀:203 作者:柒染 欄目:編程語言

這篇文章將為大家詳細講解有關如何用JVM源碼分析Java對象的創建過程,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

基于HotSpot實現對Java對象的創建過程進行深入分析。

定義兩個簡單的類AAA和BBB

如何用JVM源碼分析Java對象的創建過程

通過“javap -c AAA“`查看編譯之后的字節碼,具體如下:

如何用JVM源碼分析Java對象的創建過程

Java中的new關鍵字對應jvm中的new指令,定義在InterpreterRuntime類中,實現如下:

如何用JVM源碼分析Java對象的創建過程

new指令的實現過程:
1、其中pool是AAA的constant pool,此時AAA的class已經加載到虛擬機中,new指令后面的#2表示BBB類全限定名的符號引用在constant pool的位置;
2、方法pool->klass_at負責返回BBB對應的klassOop對象,實現如下:

如何用JVM源碼分析Java對象的創建過程

如果常量池中指定位置(#2)的數據已經是個oop類型,說明BBB的class已經被加載并解析過,則直接通過(klassOop)entry.get_oop()返回klassOop;否則表示***次使用BBB,需要解析BBB的符號引用,并加載BBB的class類,生成對應的instanceKlass對象,并更新constant pool中對應位置的符號引用;
3、klass->check_valid_for_instantiation可以防止抽象類被實例化;
4、klass->initialize實現如下:

如何用JVM源碼分析Java對象的創建過程

如果BBB的instanceKlass對象已經初始化完成,則直接返回;否則通過initialize_impl方法進行初始化,整個初始化算法分成11步,具體實現如下:

step1

如何用JVM源碼分析Java對象的創建過程

通過ObjectLocker在初始化之前進行加鎖,防止多個線程并發初始化。

step2

如何用JVM源碼分析Java對象的創建過程

如果當前instanceKlass處于being_initialized狀態,且正在被其它線程初始化,則執行ol.waitUninterruptibly等待其他線程完成后通知。

step3

如何用JVM源碼分析Java對象的創建過程

如果當前instanceKlass處于being_initialized狀態,且被當前線程初始化,則直接返回。
其實對于這個step的處理我有疑問,什么情況會走到這一步?經過RednaxelaFX大大提點,如下情況會執行step3:
例如A類有靜態變量指向一個new B類實例,B類里又有靜態變量指向new A類實例,這樣外部用A時要初始化A類,初始化過程中又要觸發B類初始化,B類初始化又再次觸發A類初始化。

step4

如何用JVM源碼分析Java對象的創建過程

如果當前instanceKlass處于fully_initialized狀態,說明已經初始化完成,則直接返回;

step5

如何用JVM源碼分析Java對象的創建過程

如果當前instanceKlass處于initialization_error狀態,說明初始化失敗了,拋出異常。

step6

如何用JVM源碼分析Java對象的創建過程

設置當前instanceKlass的狀態為 being_initialized;設置初始化線程為當前線程。

如何用JVM源碼分析Java對象的創建過程

如果當前instanceKlass不是接口類型,并且父類不為空,且還未初始化,則執行父類的初始化。

step8

如何用JVM源碼分析Java對象的創建過程

通過this_oop->call_class_initializer方法執行靜態塊代碼,實現如下:

如何用JVM源碼分析Java對象的創建過程

this_oop->class_initializer()可以獲取靜態代碼塊入口,最終通過JavaCalls::call執行代碼塊邏輯,再下一層就是具體操作系統的實現了。

step9

如何用JVM源碼分析Java對象的創建過程

如果初始化過程沒有異常,說明instanceKlass對象已經初始完成,則設置當前instanceKlass的狀態為 fully_initialized,***通知其它線程初始化已經完成;否則執行step10 and 11。

step10 and 11

如何用JVM源碼分析Java對象的創建過程

如果初始化發生異常,則設置當前instanceKlass的狀態為 initialization_error,并通知其它線程初始化發生異常。

5、如果instanceKlass初始化完成,klass->allocate_instance會在堆內存創建instanceOopDesc對象,即類的實例化;

instanceOopDesc

當在Java中new一個對象時,本質是在堆內存創建一個instanceOopDesc對象。

如何用JVM源碼分析Java對象的創建過程

instanceOopDesc在實現上繼承自oopDesc,其中oopDesc定義如下:

如何用JVM源碼分析Java對象的創建過程

當然,這只是 oopDesc的部分實現,oopDesc包含兩個數據成員:_mark 和 _metadata。
1、_mark是markOop類型對象,用于存儲對象自身的運行時數據,如哈希碼(HashCode)、GC分代年齡、鎖狀態標志、線程持有的鎖、偏向線程ID、偏向時間戳等等,占用內存大小與虛擬機位長一致,更具體的實現可以閱讀 《java對象頭的HotSpot實現分析》
2、_metadata是一個聯合體,其中wideKlassOop和narrowOop都是指向InstanceKlass對象的指針,wide版是普通指針,narrow版是壓縮類指針(compressed Class pointer)

instanceOopDesc對象的創建過程

如何用JVM源碼分析Java對象的創建過程

instanceOopDesc對象通過instanceKlass::allocate_instance進行創建,實現過程如下:
1、has_finalizer判斷當前類是否包含不為空的finalize方法;
2、size_helper確定創建當前對象需要分配多大內存;
3、CollectedHeap::obj_allocate從堆中申請指定大小的內存,并創建instanceOopDesc對象,實現如下:

如何用JVM源碼分析Java對象的創建過程

4、如果當前類重寫了finalize方法,且非空,需要把生成的對象封裝成Finalizer對象并添加到  Finalizer鏈表中,對象被GC時,如果是Finalizer對象,會將對象賦值到pending對象。Reference  Handler線程會將pending對象push到queue中,Finalizer線程poll到對象,先刪除掉Finalizer鏈表中對應的對象,然后再執行對象的finalize方法;

關于如何用JVM源碼分析Java對象的創建過程就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普宁市| 南华县| 茶陵县| 和田县| 五寨县| 扶风县| 德钦县| 牡丹江市| 句容市| 元阳县| 伽师县| 崇阳县| 金寨县| 潮州市| 朝阳县| 明溪县| 辛集市| 秦皇岛市| 龙川县| 海晏县| 满洲里市| 郎溪县| 望奎县| 建德市| 沽源县| 江达县| 财经| 兴义市| 扶绥县| 宁国市| 共和县| 蓝山县| 瓦房店市| 沙雅县| 象山县| 达尔| 新兴县| 迁安市| 孝感市| 彭阳县| 宿迁市|