日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
大話Java對象在虛擬機中是什么樣子?

大話Java對象在虛擬機中是什么樣子?

作者:Danny姜 2020-04-09 11:00:20

云計算

虛擬化 JVM本身是用C艸實現(xiàn)的,一個Java對象在是如何映射到C層的對象呢?最簡單的做法是為每個Java類生成一個結(jié)構(gòu)相同c++類與之對應(yīng)。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:申請域名、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、宜賓網(wǎng)站維護(hù)、網(wǎng)站推廣。

程序員最不缺的就是對象,每天都會給自己創(chuàng)建成百上千的對象。可是你真的了解你的對象嗎?比如以下類代碼:

 

上面代碼,在main方法中通過 new 關(guān)鍵字創(chuàng)建了Foo類的實例對象,并且通過引用 foo 指向這個對象。那么它們以及靜態(tài)變量staticValue和實例變量localValue都是被保存在內(nèi)存中什么位置,以及它們是以何種方式存在的呢?

Java OOP-Klass 模型

JVM本身是用C艸實現(xiàn)的,一個Java對象在是如何映射到C層的對象呢?

最簡單的做法是為每個Java類生成一個結(jié)構(gòu)相同c++類與之對應(yīng)。

但HotSpot JVM并沒有這么做,而是設(shè)計了一個OOP-Klass Model。這里的 OOP 指的是 Ordinary Object Pointer (普通對象指針),它用來表示對象的實例信息。而 Klass 則包含元數(shù)據(jù)和方法信息,用來描述Java類。

之所以采用這個模型是因為HotSopt JVM的設(shè)計者不想讓每個對象中都含有一個vtable(虛函數(shù)表),所以就把對象模型拆成klass和oop,其中oop中不含有任何虛函數(shù),而Klass就含有虛函數(shù)表,可以進(jìn)行method dispatch。

OOP-Klass模型 分為OOP框架和Klass框架

Klass 包含元數(shù)據(jù)和方法信息,用來描述Java類。

Klass是用來表示class的元數(shù)據(jù),包括常量池、字段、方法、類名、父類等。Klass 對象中含有虛函數(shù)表vtbl 以及父類虛函數(shù)表klass_vtbl, 因此可以根據(jù)java對象的實例類型方法的分發(fā)。

JVM 在加載class字節(jié)碼文件時,會在方法區(qū)創(chuàng)建Klass對象,其中 instanceKlass 可以認(rèn)為是 java.lang.Class 的VM級別的表示,但它們并不等價,其結(jié)構(gòu)如下圖所示,

 

上圖中的所有全局變量會在class字節(jié)碼解析階段完成賦值,主要是將常量池中的符號引用轉(zhuǎn)換為直接引用,即運行時實際內(nèi)存地址。

OOP 指的是普通對象指針,用來表示對象的實例信息

所有的 OOP 類的共同基類為 oopDesc 類。它的結(jié)構(gòu)如下:

 

當(dāng)在Java中使用 new guan'jian創(chuàng)建一個對象時,就會在JVM中創(chuàng)建一個 instanceOopDesc 實例對象。Foo中的localValue就是保存在這個對象當(dāng)中。

我們經(jīng)常說Java對象在內(nèi)存中的布局分為:對象頭、實例數(shù)據(jù)、對其填充。其實這3部分就是對應(yīng)上面圖中的 oopDesc 對象。

_mark和_metadata 一起組成了對象頭部分:

  • Mark Word:instanceOopDesc 中的 _mark 成員,允許壓縮。它用于存儲對象的運行時記錄信息,如哈希值、GC 分代年齡(Age)、鎖狀態(tài)標(biāo)志(偏向鎖、輕量級鎖、重量級鎖)、線程持有的鎖、偏向線程 ID、偏向時間戳等。
  • 元數(shù)據(jù)指針:instanceOopDesc 中的 _metadata 成員,它是聯(lián)合體,可以表示未壓縮的 Klass 指針(_klass)和壓縮的 Klass 指針。對應(yīng)的 klass 指針指向一個存儲類的元數(shù)據(jù)的 Klass 對象。

在對象頭之后,JVM會繼續(xù)填充Java對象中的具體實例數(shù)據(jù),比如Foo中的localValue。

Foo具體分析

接下來重新回到文章開頭的實例代碼,F(xiàn)oo.java中包含兩個變量staticValue和localValue,但是只有staticValue會在類加載階段由JVM分配內(nèi)存并初始化默認(rèn)值,因此當(dāng)代碼執(zhí)行到第7行時,內(nèi)存中只會在方法區(qū)創(chuàng)建Klass對象,用來描述Foo信息以及staticValue值,如下圖所示:

 

可以看出,此時堆內(nèi)存中并沒有創(chuàng)建Foo對應(yīng)的instanceOopDesc實例對象。

當(dāng)代碼執(zhí)行到第9行,調(diào)用 new 創(chuàng)建Foo時,JVM 就會創(chuàng)建一個 instanceOopDesc 對象表示這個對象的實例,然后進(jìn)行 Mark Word 的填充,將元數(shù)據(jù)指針指向剛才在方法區(qū)創(chuàng)建的 Klass 對象,并填充實例變量。并且因為方法是在main方法中執(zhí)行,所有foo指針會被保存在虛擬機棧中,并指向創(chuàng)建的 instanceOopDesc 對象。具體過程如下:

 

可以看出 localValue 是被保存在堆中的。

綜上所述:

  • foo是一個局部方法中的引用,被保存在虛擬機棧中
  • staticValue靜態(tài)變量在類加載階段被保存在方法區(qū),并被賦值
  • localValue 實例變量是在創(chuàng)建對象時才會被創(chuàng)建并賦值
  • 一個Java對象在JVM中被分成2部分:OOP和Klass。其中OOP對象保存對象里實例數(shù)據(jù),Klass用來描述類相關(guān)信息以及保存靜態(tài)變量。

分享名稱:大話Java對象在虛擬機中是什么樣子?
網(wǎng)站網(wǎng)址:http://www.dlmjj.cn/article/djpdjsh.html