真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何解密Java對象

這篇文章將為大家詳細(xì)講解有關(guān)如何解密Java對象,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識(shí)有一定的了解。

澄江ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

在Java程序運(yùn)行過程中時(shí)時(shí)刻刻都有對象被創(chuàng)建出來,對象的創(chuàng)建方式有很多種,最常見的就是new,其次還有clone和反序列化。下面我們一起來解密對象的創(chuàng)建、內(nèi)存布局以及如何定位一個(gè)對象。

對象創(chuàng)建

當(dāng)我們在創(chuàng)建對象時(shí),首先會(huì)檢查創(chuàng)建對象的類能否在常量池中定位到符號(hào)引用,并檢查符號(hào)引用代表的類是否被加載、解析和初始化過,如果沒有則必須執(zhí)行相應(yīng)的類加載過程(這個(gè)后面也會(huì)單獨(dú)寫一篇文章講解)。

對象創(chuàng)建的過程大約有以下幾步:

  1. 虛擬機(jī)為對象分配內(nèi)存。對象所需內(nèi)存的大小在類加載完成以后便可完全確定。
  2. 設(shè)置對象必要信息。如對象是哪個(gè)類的實(shí)例、對象的hash碼、對象的GC分代年齡等信息
  3. 第三步執(zhí)行的時(shí)候,虛擬機(jī)其實(shí)認(rèn)為對象已經(jīng)創(chuàng)建成功,但是從Java程序的角度并沒有完成,下面會(huì)接著執(zhí)行方法,把對象按照編寫的代碼進(jìn)行初始化
 
分配對象內(nèi)存

為對象分配內(nèi)存本質(zhì)上就是從Java堆中劃分出一塊固定大小的內(nèi)存給Java對象使用。對象內(nèi)存分配主要有兩種:

  • 指針碰撞
  • 空閑列表

具體使用哪種方式取決于堆內(nèi)存是否工整,堆內(nèi)存是否工整本質(zhì)又取決于垃圾回收器是否帶有壓縮整理功能。

指針碰撞的分配方式用于在內(nèi)存工整的堆中進(jìn)行對象分配,所有被使用的內(nèi)存放在一邊,未被使用的在另一邊,中間放著一個(gè)指針作為分界點(diǎn)的指示器,當(dāng)為對象分配內(nèi)存時(shí),只需要將指針往未被使用的一邊挪動(dòng)與對象相等大小的距離就可以。

空閑列表適合在不規(guī)整的內(nèi)存中為對象分配內(nèi)存,虛擬機(jī)為了知道哪些內(nèi)存區(qū)域可用,必須維護(hù)一個(gè)列表,當(dāng)進(jìn)行內(nèi)存分配時(shí),則在列表中選取一個(gè)足夠大的空間劃分給對象使用。

對象分配在虛擬機(jī)中的分配并不是線程安全的,為了解決這個(gè)問題,主要有兩種解決方法:

  • CAS + 失敗重試
  • TLAB:每個(gè)線程預(yù)先在Java堆中預(yù)先分配一小塊內(nèi)存,稱為TLAB(本地線程分配緩沖),哪個(gè)線程需要分配內(nèi)存,就在哪個(gè)線程的TLAB上分配。只有TLAB用完了并且分配新的TLAB時(shí)需要同步鎖定。
 
對象內(nèi)存布局

對象在內(nèi)存中的布局主要有三塊:

  • 對象頭
  • 實(shí)例數(shù)據(jù)
  • 對齊填充
 
對象頭

對象頭主要用來存儲(chǔ)兩塊信息:

  • 存儲(chǔ)對象自身運(yùn)行的數(shù)據(jù)
  • 類型指針

對象自身運(yùn)行時(shí)的數(shù)據(jù)主要包括:哈希碼、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時(shí)間戳等。這部分?jǐn)?shù)據(jù)的長度在32位和64位的虛擬機(jī)(未開啟壓縮指針)中分別為32位和64位。

存儲(chǔ)內(nèi)容標(biāo)志位狀態(tài)
對象哈希碼、對象分代年齡01未鎖定
指向鎖記錄的指針00輕量級(jí)鎖定
指向重量級(jí)鎖的指針10膨脹(重量級(jí)鎖定)
空,不需要記錄信息11GC標(biāo)記
偏向線程ID、偏向時(shí)間戳、對象分代年齡01可偏向

類型指針可以用來確定這個(gè)對象是哪個(gè)類的實(shí)例,但虛擬機(jī)的實(shí)現(xiàn)不是必須在對象上保留類型指針。

 
實(shí)例數(shù)據(jù)

實(shí)例數(shù)據(jù)是對象真正存儲(chǔ)的有效信息,就是代碼中各種類型字段的內(nèi)容,無論是從父類還是子類中定義的,內(nèi)容存儲(chǔ)的順序會(huì)受到虛擬機(jī)分配策略參數(shù)和字段在Java源碼中定義順序的影響。但是相同寬度的字段會(huì)分配到一起,在這個(gè)前提條件下,子類較窄的變量會(huì)插到父類變量的空隙之中。

 
對齊填充

對齊填充并不是必然存在,由于虛擬機(jī)的內(nèi)存管理要求對象其實(shí)地址必須是8字節(jié)的整數(shù)倍,也就是對象大小必須是8字節(jié)的整數(shù)倍,因此當(dāng)對象實(shí)例不是8字節(jié)的整數(shù)倍大小時(shí),需要通過對齊填充補(bǔ)全。

 
對象訪問

對象建立以后我們需要使用它,我們可以通過Java棧上的reference來操作堆上的具體對象,但是如何通過reference來找到具體的對象則是需要我們?nèi)ソ鉀Q的,目前主要有兩種方式:

  • 句柄
  • 直接指針

下圖是采用句柄的方式去訪問對象如何解密Java對象

下圖是采用直接指針的方式去訪問對象

如何解密Java對象  


通過上述兩種圖的對比,我們可以看出句柄的優(yōu)勢在于棧中的reference存儲(chǔ)的內(nèi)容是穩(wěn)定的句柄地址,不會(huì)因?yàn)閷ο蟮囊苿?dòng)而改變,但訪問會(huì)遜于直接指針,因?yàn)槎嗔艘淮沃羔樁ㄎ坏臅r(shí)間開銷。

直接指針的訪問方式的最大好處就是速度快,節(jié)省了一次指針定位的時(shí)間開銷。

關(guān)于如何解密Java對象就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


新聞標(biāo)題:如何解密Java對象
網(wǎng)站鏈接:http://weahome.cn/article/peijgd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部