国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java對(duì)象內(nèi)存布局解析

charles_paul / 2729人閱讀

摘要:堆內(nèi)存用于存放我們?cè)诔绦蛑袆?chuàng)建的對(duì)象,一旦沒有足夠的空間用于存放這些對(duì)象,即會(huì)拋出異常。當(dāng)我們采用后一種方式時(shí),我們需要了解一個(gè)對(duì)象是如何占據(jù)堆內(nèi)存空間的,或者說(shuō)是了解一個(gè)對(duì)象是由哪些部分組成的。

JVM將內(nèi)存劃分為程序計(jì)數(shù)器(Program Counter Register)、虛擬機(jī)棧(VM Stack)、本地方法棧(Native Method Stack)、堆(Heap)以及方法區(qū)(Method Area)。作為開發(fā)者,我們最關(guān)注的是虛擬機(jī)棧以及堆這兩塊區(qū)域。虛擬機(jī)棧所需要的內(nèi)存空間在編譯期間即可明確,而堆內(nèi)存所需要的空間需要在運(yùn)行時(shí)才可確定。堆內(nèi)存用于存放我們?cè)诔绦蛑袆?chuàng)建的對(duì)象,一旦沒有足夠的空間用于存放這些對(duì)象,即會(huì)拋出OutOfMemoryError異常。在這種情況下,我們可以調(diào)整堆內(nèi)存的大小,或者對(duì)程序進(jìn)行優(yōu)化。當(dāng)我們采用后一種方式時(shí),我們需要了解一個(gè)對(duì)象是如何占據(jù)堆內(nèi)存空間的,或者說(shuō)是了解一個(gè)對(duì)象是由哪些部分組成的。

對(duì)象的內(nèi)存布局

HotSpot虛擬機(jī)中,對(duì)象在內(nèi)存中的布局劃分為3個(gè)區(qū)域:對(duì)象頭(Header),實(shí)例數(shù)據(jù)(Instance Data)以及對(duì)齊填充(Padding)。

對(duì)象頭

HotSpot虛擬機(jī)對(duì)象的對(duì)象頭一般包含兩部分信息,第一部分用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),例如HashCodeGC分代年齡等信息。在32位和64位的JVM中,這部分?jǐn)?shù)據(jù)分別為32bit64bit,官方稱這部分?jǐn)?shù)據(jù)為Mark Word

另一部分用于存儲(chǔ)對(duì)象的類型指針,該指針指向它的類元數(shù)據(jù),JVM通過(guò)這個(gè)指針確定對(duì)象是哪個(gè)類的實(shí)例。在32JVM中,指針的長(zhǎng)度為32bit,在未開啟壓縮指針的64JVM中,該指針的長(zhǎng)度為64bit,如果開啟壓縮指針,那么為32bit

之前提到對(duì)象頭一般包含兩部分信息,這是因?yàn)槿绻麑?duì)象是一個(gè)數(shù)組,那么對(duì)象頭還需要有額外的空間用于存儲(chǔ)數(shù)組的長(zhǎng)度,并且這部分?jǐn)?shù)據(jù)也隨著JVM位數(shù)的不同而不同:32位的JVM上,該區(qū)域的長(zhǎng)度為32bit,在64位未開啟壓縮指針的JVM中,這部分?jǐn)?shù)據(jù)的長(zhǎng)度為64bit,否則為32bit

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

實(shí)例數(shù)據(jù)部分是對(duì)象真正存儲(chǔ)有效信息的區(qū)域,存儲(chǔ)了代碼中定義的各種字段的內(nèi)容,包括從父類繼承下來(lái)的字段和子類中定義的字段。

實(shí)例數(shù)據(jù)緊隨對(duì)象頭,為了提高存儲(chǔ)空間的利用率,這部分?jǐn)?shù)據(jù)的存儲(chǔ)順序會(huì)受到虛擬機(jī)分配策略參數(shù)和字段在Java源碼中定義順序的影響。HotSpot虛擬機(jī)默認(rèn)的分配策略如下所示。

doubles & longs

ints & floats

shorts & chars

booleans & bytes

references

可以看出,相同寬度的字段總是被分配到一起,并且在滿足這個(gè)條件的前提下,在父類中定義的字段會(huì)出現(xiàn)在子類字段之前。

對(duì)齊填充

對(duì)齊填充這部分不是必須存在的,這部分僅僅是起著占位符的作用。由于HotSpot虛擬機(jī)的自動(dòng)內(nèi)存管理系統(tǒng)要求對(duì)象的起始地址必須是8字節(jié)的整數(shù)倍,因此當(dāng)對(duì)象實(shí)例部分?jǐn)?shù)據(jù)沒有對(duì)齊時(shí),就需要對(duì)剩余的部分進(jìn)行填充。

度量工具

JDK 5開始, Java提供了Instrumentation API,通過(guò)getObjectSize方法來(lái)獲取對(duì)象的大小,但是getObjectSize方法存在如下兩個(gè)缺陷,不能準(zhǔn)確的計(jì)算對(duì)象的大小。

不能直接調(diào)用getObjectSize方法,而是需要通過(guò)-javaagent參數(shù)指定一個(gè)特定的jar文件(包含Instrumentation代理)來(lái)啟動(dòng)Instrumentation的代理程序。

如果一個(gè)對(duì)象中包含別的對(duì)象的引用,那么getObjectSize方法僅僅計(jì)算引用的大小,而不包括引用所指向的對(duì)象的大小。

由于上述兩個(gè)缺陷,我們不能直接調(diào)用getObjectSize方法來(lái)計(jì)算對(duì)象的大小,但是利用Java的反射機(jī)制,我們可以完整的計(jì)算一個(gè)對(duì)象的大小。我們解析對(duì)象的每一個(gè)Field(使用getDeclaredFields),并遵從如下規(guī)則。

當(dāng)Field是基本數(shù)據(jù)類型時(shí),我們不再計(jì)算該Field的大小,因?yàn)樵?b>Field的大小已經(jīng)被包含在getObjectSize方法的返回值中。

當(dāng)Field是靜態(tài)數(shù)據(jù)或者是常量池中包含的數(shù)據(jù),那么我們忽略這些數(shù)據(jù),因?yàn)檫@些數(shù)據(jù)并不是屬于對(duì)象的。

我們需要保存我們已經(jīng)計(jì)算過(guò)的對(duì)象的引用,防止重復(fù)計(jì)算。

如果對(duì)象所屬的類存在父類,還需要計(jì)算父類中成員變量的大小。

jvm-obj-size 是以上思想的具體實(shí)現(xiàn),jvm-obj-size 實(shí)現(xiàn)了基本的獲取對(duì)象本身的大小(sizeOf,僅包含引用本身),以及獲取對(duì)象真正的大小(fullSizeOf,包含引用所指向的對(duì)象)的方法,具體用法以及測(cè)試代碼詳見README文件。

參考

深入理解Java虛擬機(jī)

Again about determining size of Java object

Java SE 6 新特性: Instrumentation 新功能

Java對(duì)象大小內(nèi)幕淺析

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/66290.html

相關(guān)文章

  • 四年來(lái)Android面試大綱,作為一個(gè)Android程序員

    摘要:再附一部分架構(gòu)面試視頻講解本文已被開源項(xiàng)目學(xué)習(xí)筆記總結(jié)移動(dòng)架構(gòu)視頻大廠面試真題項(xiàng)目實(shí)戰(zhàn)源碼收錄 Java反射(一)Java反射(二)Java反射(三)Java注解Java IO(一)Java IO(二)RandomAccessFileJava NIOJava異常詳解Java抽象類和接口的區(qū)別Java深拷貝和淺拷...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 讀書筆記之深入理解Java虛擬機(jī)

    摘要:前言本文內(nèi)容基本摘抄自深入理解虛擬機(jī),以供復(fù)習(xí)之用,沒有多少參考價(jià)值。此區(qū)域是唯一一個(gè)在虛擬機(jī)規(guī)范中沒有規(guī)定任何情況的區(qū)域。堆是所有線程共享的內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。虛擬機(jī)上把方法區(qū)稱為永久代。 前言 本文內(nèi)容基本摘抄自《深入理解Java虛擬機(jī)》,以供復(fù)習(xí)之用,沒有多少參考價(jià)值。想要更詳細(xì)了解請(qǐng)參考原書。 第二章 1.運(yùn)行時(shí)數(shù)據(jù)區(qū)域 showImg(https://segment...

    jaysun 評(píng)論0 收藏0
  • Activity系列博客5篇

    摘要:通過(guò)分析源碼,不難發(fā)現(xiàn),主要是通過(guò)循環(huán)解析文件并將信息解析到內(nèi)存對(duì)象,布局文件中定義的一個(gè)個(gè)組件都被順序的解析到了內(nèi)存中并被父子的形式組織起來(lái),這樣通過(guò)給定的一個(gè)就可以將整個(gè)布局文件中定義的組件全部解析。 目錄介紹 01.前沿介紹 02.handleLaunchActivity 03.performLaunchActivity 04.activity.attach 05.Activi...

    yangrd 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<