JVM底層部分面試題

解釋一下對象的創建過程(半初始化)

  • Object o = new Object();

    • new Object()先在內存中申請空間,創建出對象,半初始化;
    • o在main方法棧幀中產生,存放堆中對象的內存地址;
    • 最後指針指向堆對象,建立關聯。

    詳細參考:圖解JAVA對象的創建過程

DCL單例到底需不需要加volatile?(單例模式,指令重排)

在這裏插入圖片描述

  • DCL:double check lock雙重檢測鎖;
  • 用volatile修飾的對象,會禁止對該對象存儲位置操作的指令重排。
  • 通過問題一我們知道對象創建分爲三個步驟,這三個步驟之間有可能會發生指令重排。多線程條件下,一個線程操作對象:執行完半初始化,下一步可能會先建立連接再執行對象的init方法,另一個線程可能會在對象建立完連接便提取對象,此時對象處於半初始化狀態。
  • volatile:禁止指令重排,會避免使用到半初始化狀態的對象。
    在這裏插入圖片描述

對象在內存中的存儲佈局(對象和數組的存儲不同)

在這裏插入圖片描述

對象頭包括什麼?(Markword,class pointer)

  • markword:hashcode、gc、鎖信息(讀hotspot源碼)(8個字節)
  • class pointer 指向類對象(開啓壓縮4個字節,不壓縮8個字節)
    在這裏插入圖片描述

對象怎麼定位?(直接、間接)

在這裏插入圖片描述

  • hotsopot的具體實現,實現方式是直接指針。

  • 句柄(間接)方式:方便gc操作,GC需要經常移動對象。

對象怎麼分配?(棧上-線程本地-Edum-Old)

在這裏插入圖片描述

  • jvm讀到new關鍵字,首先會嘗試在棧上分配對象(經過逃逸分析和標量計算),棧上創建對象的好處:棧內對象出棧之後,生命週期結束,不需要GC介入。。
  • TLAB:thread local allcation buffer 線程本地分配緩衝區,管理線程的分配競爭。

Object o = new Object()在內存中佔多少個字節?

=右邊:

  • class pointer: 指向類對象(開啓壓縮4個字節,不壓縮8個字節)

  • markword:hashcode、gc、鎖信息(讀hotspot源碼)(8個字節)

  • instance data:按數據量變化,沒有則爲0字節

  • 最後對齊(被8整除)

=左邊:

  • o也佔用空間,壓縮4個字節,不壓縮8個字節。

爲什麼hotspot不使用c++對象來代表java對象?

  • vritual pointer虛函數表的指針在c++有,在java沒有。

Class對象是在堆還是方法區?

在這裏插入圖片描述

對象的創建與OOP-Klass模型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章