成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

charles_paul / 2787人閱讀

摘要:堆內(nèi)存用于存放我們在程序中創(chuàng)建的對象,一旦沒有足夠的空間用于存放這些對象,即會拋出異常。當(dāng)我們采用后一種方式時,我們需要了解一個對象是如何占據(jù)堆內(nèi)存空間的,或者說是了解一個對象是由哪些部分組成的。

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

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

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

對象頭

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

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

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

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

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

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

doubles & longs

ints & floats

shorts & chars

booleans & bytes

references

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

對齊填充

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

度量工具

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

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

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

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

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

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

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

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

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

參考

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

Again about determining size of Java object

Java SE 6 新特性: Instrumentation 新功能

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

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

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

相關(guān)文章

  • 四年來Android面試大綱,作為一個Android程序員

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

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

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

    jaysun 評論0 收藏0
  • Activity系列博客5篇

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

    yangrd 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<