成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java對象結(jié)構(gòu)及大小計算

winterdawn / 2162人閱讀

摘要:由于的自動內(nèi)存管理系統(tǒng)要求對象起始地址必須是字節(jié)的整數(shù)倍,換句話說,就是對象的大小必須是字節(jié)的整數(shù)倍。對象大小計算要點(diǎn)在位系統(tǒng)下,存放指針的空間大小是字節(jié),是字節(jié),對象頭為字節(jié)。靜態(tài)屬性不算在對象大小內(nèi)。

jvm系列

垃圾回收基礎(chǔ)

JVM的編譯策略

GC的三大基礎(chǔ)算法

GC的三大高級算法

GC策略的評價指標(biāo)

JVM信息查看

GC通用日志解讀

jvm的card table數(shù)據(jù)結(jié)構(gòu)

Java類初始化順序

Java對象結(jié)構(gòu)及大小計算

Java的類加載機(jī)制

Java對象分配簡要流程

年老代過大有什么影響

Survivor空間溢出實(shí)例

關(guān)于Object=null

Java線程與Xss

本文主要簡述Java對象的內(nèi)存布局以及其大小的計算。

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

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

對象頭

HotSpot虛擬機(jī)的對象頭包括兩部分信息:

第一部分markword,用于存儲對象自身的運(yùn)行時數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程ID、偏向時間戳等,這部分?jǐn)?shù)據(jù)的長度在32位和64位的虛擬機(jī)(未開啟壓縮指針)中分別為32bit和64bit,官方稱它為“MarkWord”。

對象頭的另外一部分是klass,類型指針,即對象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個指針來確定這個對象是哪個類的實(shí)例.

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

實(shí)例數(shù)據(jù)部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內(nèi)容。無論是從父類繼承下來的,還是在子類中定義的,都需要記錄起來。

對齊填充

第三部分對齊填充并不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。由于HotSpot VM的自動內(nèi)存管理系統(tǒng)要求對象起始地址必須是8字節(jié)的整數(shù)倍,換句話說,就是對象的大小必須是8字節(jié)的整數(shù)倍。而對象頭部分正好是8字節(jié)的倍數(shù)(1倍或者2倍),因此,當(dāng)對象實(shí)例數(shù)據(jù)部分沒有對齊時,就需要通過對齊填充來補(bǔ)全。

對象大小計算 要點(diǎn)

在32位系統(tǒng)下,存放Class指針的空間大小是4字節(jié),MarkWord是4字節(jié),對象頭為8字節(jié)。

在64位系統(tǒng)下,存放Class指針的空間大小是8字節(jié),MarkWord是8字節(jié),對象頭為16字節(jié)。

64位開啟指針壓縮的情況下,存放Class指針的空間大小是4字節(jié),MarkWord是8字節(jié),對象頭為12字節(jié)。

數(shù)組長度4字節(jié)+數(shù)組對象頭8字節(jié)(對象引用4字節(jié)(未開啟指針壓縮的64位為8字節(jié))+數(shù)組markword為4字節(jié)(64位未開啟指針壓縮的為8字節(jié)))+對齊4=16字節(jié)。

靜態(tài)屬性不算在對象大小內(nèi)。

實(shí)例
import java.util.HashMap;
/**
 * 64位開啟指針壓縮的話,markword變成8字節(jié),壓縮了class指針為4字節(jié),故對象頭12字節(jié)
 * 64位沒有開啟指針壓縮的話,markword8字節(jié),class指針8字節(jié),對象頭16字節(jié)
 * 32位markword為4字節(jié),class指針為4字節(jié),對象頭8字節(jié)
 *
 * 另外,靜態(tài)屬性所占用的空間通常不算在對象本身,因?yàn)樗囊檬窃诜椒▍^(qū)。
 *
 * @author xixicat
 * @created 2014-10-03
 */
public class ObjectSize {
    public static void main(String[] args){
        System.out.println(SizeOfTool.getObjectSize(new A(),SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new B(),SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new C(),SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new D(),SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new E(),SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new Q(),SizeEnum.B));
        /**
         * 64位壓縮指針下,對象頭12字節(jié),數(shù)組長度描述4字節(jié),數(shù)據(jù)4*100 =16+400 = 416
         */
        System.out.println(SizeOfTool.getObjectSize(new int[100],SizeEnum.B));
        /**
         * 屬性4位對齊
         * 64位壓縮指針下,對象頭12字節(jié),數(shù)組長度描述4字節(jié),數(shù)據(jù)1*100,對齊后104 = 16+104 = 120
         */
        System.out.println(SizeOfTool.getObjectSize(new byte[100],SizeEnum.B));
        /**
         * 二維數(shù)組
         * 64位指針壓縮下
         * 第1維數(shù)組,對象頭12字節(jié),數(shù)組長度描述4字節(jié),2個數(shù)組引用共8字節(jié),共24字節(jié)
         * 第2維數(shù)組,對象頭12字節(jié),數(shù)組長度描述4字節(jié),100個數(shù)組引用共400字節(jié),對齊后共416字節(jié)
         *         第1維的2個引用所指對象大小 = 2*416 = 832 字節(jié)
         *         共24+832 = 856字節(jié)
         */
        System.out.println(SizeOfTool.getObjectSize(new int[2][100],SizeEnum.B));
        /**
         * 二維數(shù)組
         * 64位指針壓縮下
         * 第1維數(shù)組,對象頭12字節(jié),數(shù)組長度描述4字節(jié),100個數(shù)組引用共400字節(jié),共416字節(jié)
         * 第2維數(shù)組,對象頭12字節(jié),數(shù)組長度描述4字節(jié),2個數(shù)組引用共8字節(jié),共24字節(jié)
         *         第1維的100個引用所指對象大小 = 100*24 = 2400 字節(jié)
         *         共416+2400 = 2816字節(jié)
         */
        System.out.println(SizeOfTool.getObjectSize(new int[100][2],SizeEnum.B));
        System.out.println(SizeOfTool.getObjectSize(new Object(),SizeEnum.B));
        /**
         * 不算static屬性
         * private final char value[];
         * private int hash; // Default to 0
         * private transient int hash32 = 0;
         *
         * 32位下,String對象頭8字節(jié),2個int類型8字節(jié),char數(shù)組引用占4字節(jié),共占24字節(jié)
         *        另外,還要算上value[]數(shù)組的占用,數(shù)組對象頭部8字節(jié),數(shù)組長度4字節(jié),對齊后共占16字節(jié)
         *    =》String對象對象大小24+16 = 40字節(jié)
         * 64位開啟指針壓縮下(壓縮指針),String對象頭12字節(jié),2個int類型8字節(jié),char數(shù)組引用占4字節(jié),共占24字節(jié)
         *        另外,還要算上value[]數(shù)組的占用,數(shù)組對象頭部12字節(jié),數(shù)組長度4字節(jié),對齊后共占16字節(jié)
         *    =》String對象大小24+16=40字節(jié)
         */
        System.out.println(SizeOfTool.getObjectSize(new String(),SizeEnum.B));
        /**
         *  transient Entry[] table = (Entry[]) EMPTY_TABLE;
         *  transient int size;
         *  int threshold;
         *  final float loadFactor;
         *  transient int modCount;
         *
         * 64位開啟指針壓縮下,對象頭部12字節(jié),數(shù)組引用4字節(jié),3個int12字節(jié),float4字節(jié),共32字節(jié)
         *                 另外,算上Entry[] = 對象頭12 +屬性16字節(jié)+數(shù)組長度4字節(jié) = 32字節(jié)
         *
         *                 final K key;
         *                 V value;
         *                 Entry next;
         *                 int hash;
         *
         *                 對象頭12字節(jié),3個引用共12字節(jié),1個int4字節(jié)  =》 一個entry至少占用28字節(jié)
         *
         *             =》32+32=64字節(jié)
         */
        System.out.println(SizeOfTool.getObjectSize(new HashMap(),SizeEnum.B));
    }
}
//32位下對象頭8字節(jié),byte占1字節(jié),對其填充后,總占16字節(jié)
//64位開啟指針壓縮下對象頭12字節(jié),byte1字節(jié),對齊后占16字節(jié)
class A{
    byte b1;
}
//32位下對象頭8字節(jié),8個byte8字節(jié),總16字節(jié)
//64位開啟指針壓縮下對象頭12字節(jié),8個byte8字節(jié),對齊后占24字節(jié)
class B{
    byte b1,b2,b3,b4,b5,b6,b7,b8;
}
//32位下對象頭8字節(jié),9個byte9字節(jié),對其填充后,總24字節(jié)
//64位開啟指針壓縮下對象頭12字節(jié),9個byte9字節(jié),對齊后占24字節(jié)
class C{
    byte b1,b2,b3,b4,b5,b6,b7,b8,b9;
}
//32位下對象頭8字節(jié),int占4字節(jié),引用占4字節(jié),共16字節(jié)
//64位開啟指針壓縮下對象頭12字節(jié),int占4字節(jié),引用占4字節(jié),對齊后占24字節(jié)
class D{
    int i;
    String str;
}
//32位下對象頭8字節(jié),int4字節(jié),byte占1字節(jié),引用占4字節(jié),對其后,共24字節(jié)
//64位開啟指針壓縮下對象頭12字節(jié),int占4字節(jié),引用占4字節(jié),byte占1字節(jié),對齊后占24字節(jié)
class E{
    int i;
    byte b;
    String str;
}
/**
 * 對齊有兩種
 * 1、整個對象8字節(jié)對齊
 * 2、屬性4字節(jié)對齊   ****
 *
 * 對象集成屬性的排布
 * markword     4          8
 * class指針     4          4
 * 父類的父類屬性  1         1
 * 屬性對齊       3         3
 * 父類的屬性     1          1
 * 屬性對齊       3          3
 * 當(dāng)前類的屬性    1         1
 * 屬性對齊填充    3          3
 * 整個對象對齊   8+12 =》 24    12+12=》24
 */
class O{
    byte b;
}
class P extends O{
    byte b;
}
class Q extends P{
    byte b;
}
參考

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

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65601.html

相關(guān)文章

  • Java對象內(nèi)存占用分析

    摘要:對于不同的實(shí)現(xiàn),對象占用的內(nèi)存空間大小可能不盡相同,本文主要分析中的情況,實(shí)驗(yàn)環(huán)境為位系統(tǒng),使用進(jìn)行結(jié)論驗(yàn)證。內(nèi)存占用這里分析一個只有一組鍵值對的結(jié)構(gòu)如下首先分析本身的大小。 本文深入分析并驗(yàn)證了不同Java對象占用內(nèi)存空間大小的情況。對于不同的jvm實(shí)現(xiàn),Java對象占用的內(nèi)存空間大小可能不盡相同,本文主要分析HotSpot jvm中的情況,實(shí)驗(yàn)環(huán)境為64位window10系統(tǒng)、JD...

    JouyPub 評論0 收藏0
  • 想進(jìn)大廠?50個多線程面試題,你會多少?(一)

    摘要:下面是線程相關(guān)的熱門面試題,你可以用它來好好準(zhǔn)備面試。線程安全問題都是由全局變量及靜態(tài)變量引起的。持有自旋鎖的線程在之前應(yīng)該釋放自旋鎖以便其它線程可以獲得自旋鎖。 最近看到網(wǎng)上流傳著,各種面試經(jīng)驗(yàn)及面試題,往往都是一大堆技術(shù)題目貼上去,而沒有答案。 不管你是新程序員還是老手,你一定在面試中遇到過有關(guān)線程的問題。Java語言一個重要的特點(diǎn)就是內(nèi)置了對并發(fā)的支持,讓Java大受企業(yè)和程序員...

    wow_worktile 評論0 收藏0
  • Java 內(nèi)存結(jié)構(gòu)備忘錄

    摘要:本文詳細(xì)描述了堆內(nèi)存模型,垃圾回收算法以及處理內(nèi)存泄露的最佳方案,并輔之以圖表,希望能對理解內(nèi)存結(jié)構(gòu)有所幫助。該區(qū)域也稱為內(nèi)存模型的本地區(qū)。在中,內(nèi)存泄露是指對象已不再使用,但垃圾回收未能將他們視做不使用對象予以回收。 本文詳細(xì)描述了 Java 堆內(nèi)存模型,垃圾回收算法以及處理內(nèi)存泄露的最佳方案,并輔之以圖表,希望能對理解 Java 內(nèi)存結(jié)構(gòu)有所幫助。原文作者 Sumith Puri,...

    wow_worktile 評論0 收藏0
  • Java對象分配簡要流程

    摘要:在一般應(yīng)用中,不會逃逸的局部對象所占的比例很大,如果能使用棧上分配,那大量的對象就會隨著方法的結(jié)束而自動銷毀了,垃圾收集系統(tǒng)的壓力將會小很多。相關(guān)參數(shù)設(shè)置大對象直接進(jìn)入年老代的閾值,當(dāng)對象大小超過這個值時,將直接在年老代分配。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級算法 GC策略的評價指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card t...

    zorro 評論0 收藏0
  • 類的認(rèn)識使用

    摘要:注意空類的大小,空類比較特殊,編譯器給了空類一個字節(jié)來唯一標(biāo)識這個類。如果一個類沒有對象,那么它的對象需要給進(jìn)行占位,標(biāo)識對象存在,這不存儲有效數(shù)據(jù)。 類 類的使...

    alexnevsky 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<