每日一面——從JVM層面談談你對“對象”的理解

菜雞每日一面系列打卡25

每天一道面試題目 

助力小夥伴輕鬆拿offer

堅持就是勝利,我們一起努力!

題目描述

JVM層面談談你對“對象”的理解。

題目分析

在開始之前,菜雞想先引用一句非常經典的話,“JavaC++之間有一堵由內存動態分配和垃圾收集技術所圍成的高牆,牆外面的人想進去,牆裏面的人卻想出來。”這簡直是程序員版的現實圍城。而這段話裏提到的內存動態分配和垃圾收集技術,都與“對象”這個詞脫不了干係。

衆所周知(對了解Java的人而言),Java是一門面向對象的語言。“對象”這個概念已經深入了每個面嚮對象語言程序員的內心,這包括但不限於JavaC++Python……而本文將要探究的就是JVM層面對象的概念。理解了這一概念,會對面向對象有更加深刻的認識。

題目解答

01

對象的創建

Java的世界裏永遠不缺“對象”,如果缺,new一個。就是這個神奇的new關鍵字,分分鐘解決了現實世界中找“對象”的難題。究竟是怎麼做到的呢?這種神祕的力量值得我們仔細研究一波。注意,下文所提到的對象僅限於普通Java對象,不包括數組和Class對象等。

首先,需要了解Java程序運行的大致過程,我們編寫的源程序(.java文件)經過編譯器編譯之後得到(.class文件),這也是Java跨平臺的關鍵,然後JVM將字節碼文件解釋成機器碼運行。

接下來,我們用一張圖來描述當JVM遇到一條字節碼的new指令時的反應。

注意,這張圖僅僅描述的是JVM層面創建對象的流程,至此,其實並沒有得到你想要的對象,後續會執行Class文件中的<init>()方法進行對象初始化。

02

對象的內存佈局

第一部分的圖中中提到了對象頭這個概念。在HotSpot虛擬機裏,對象在堆內存中的存儲佈局可以劃分爲三個部分:對象頭實例數據對齊填充

  • 對象頭的內容可分爲兩部分:Mark Word類型指針

    • Mark Word的內容如下表所示:

    • 類型指針(非必須)則是對象指向它的類型元數據的指針,JVM通過這個指針來確定該對象是哪個類的實例。

  • 實例數據存儲的是對象的有效信息,即我們在程序中定義的類的屬性(包括從父類繼承的)。

  • 對齊填充起到佔位符的作用。HotSpot虛擬機的自動內存管理系統要求對象起始地址必須是8字節的整數倍,也即任何對象的大小都必須是8字節的整數倍。對象頭部分已經被設計成天然滿足8字節的整數倍了,而對象的實例數據部分如果不滿足,就需要進行對齊填充。

03

對象的訪問定位

常見的對象訪問定位方式主要有兩種:句柄訪問直接指針訪問

  • 句柄訪問

    過程

    ① reference → 句柄池(包括實例數據指針與類型數據指針)

    ②實例數據指針 → 對象實例數據、類型數據指針 → 對象類型數據

    優勢

    reference中存儲的是穩定句柄地址,在對象被移動時只會改變句柄中的實例數據指針,而不改變reference

  • 直接指針訪問

    過程

    reference → 對象實例數據

    ②對象實例數據  對象類型數據

    優勢

    速度更快,節省了一次指針定位的時間開銷。

參考資料

《深入理解Java虛擬機》第3版 周志明

相關鏈接

每日一面——談談你對JVM的運行時數據區的理解

以上便是菜雞對JVM層面對象的一些總結,供大家參考。

學習 | 工作 | 分享

????長按關注“有理想的菜雞

只有你想不到,沒有你學不到

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