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

資訊專欄INFORMATION COLUMN

java 對象內(nèi)存大小

xiaokai / 2188人閱讀

摘要:一個(gè)對象內(nèi)存有多大為什么想知道這個(gè),自以為很重要,其實(shí)。參考鏈接對象解析不得不了解的對象頭從開始在位系統(tǒng)上會默認(rèn)開啟壓縮指針研究位引用指針壓縮技術(shù)

java 一個(gè)對象內(nèi)存有多大
為什么想知道這個(gè),自以為很重要,其實(shí) just for fun =。=
測試相關(guān)說明

jdk: java 官網(wǎng)上下載的,HotSpot 虛擬機(jī)

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

使用的方法: Instrumentation 參考的是 一個(gè)對象占用多少字節(jié)?

確認(rèn)編譯時(shí)是 32 位還是 64 位,對測試結(jié)果有影響。x86 為 32 位, amd64 為 64 位,其余我不知道

System.out.println(System.getProperty("os.arch"));

準(zhǔn)備工作

SizeOfObject.java 直接從上面鏈接上拷貝

編譯這個(gè)類,得到 .class 文件

在包名路徑下執(zhí)行一下命令進(jìn)行打包(注意修改相應(yīng)的包名):

jar cvfm SizeOfObject.jar manifest.mf org/seal_de/SizeOfObject.class

其中 manifest.mf 清單信息為: PreMain-Class: org.seal_de.SizeOfObject

PS: 如果在打包好的 jar 包中,META-INF/MANIFEST.MF 沒有 PreMain-Class 屬性,添加上去即可

在運(yùn)行測試程序的時(shí)候,添加 vm 參數(shù)

-javaagent:{jar包路徑}SizeOfObject.jar

測試用例

測試 int, Object, 引用的大小。其余類型測試都類似

public class MemoryTest {
    /**
     * -javaagent:{jar包路徑}SizeOfObject.jar -XX:+UseCompressedOops
     * 使用指針壓縮,在一定情況下64位HotSpot jvm默認(rèn)指針壓縮
     *
     *Output:
     *amd64
     *Object:                              16
     *    
     *include one int:                     16
     *include two int:                     24
     *include three int:                   24
     *
     *include one object:                  16
     *include one object:                  24
     */
    static void test1() {
        System.out.println(System.getProperty("os.arch"));
        System.out.printf("%-30s%9d
", "Object:", SizeOfObject.sizeOf(new Object()));
        System.out.println();
        System.out.printf("%-30s%9d
", "include one int:", SizeOfObject.sizeOf(new IntegerTestOne()));
        System.out.printf("%-30s%9d
", "include two int:", SizeOfObject.sizeOf(new IntegerTestTwo()));
        System.out.printf("%-30s%9d
", "include three int:", SizeOfObject.sizeOf(new IntegerTestThree()));
        System.out.println();
        System.out.printf("%-30s%9d
", "include one object:", SizeOfObject.sizeOf(new ReferenceTestOne()));
        System.out.printf("%-30s%9d
", "include one object:", SizeOfObject.sizeOf(new ReferenceTestTwo()));
    }

    /**
     * -javaagent:{jar包路徑}SizeOfObject.jar -XX:-UseCompressedOops
     * 不使用指針壓縮
     *
     *Output:
     *amd64
     *Object:                              16
     *
     *include one int:                     24
     *include two int:                     24
     *include three int:                   32
     *
     *include one object:                  24
     *include one object:                  32
     */
    static void test2() {
        System.out.println(System.getProperty("os.arch"));
        System.out.printf("%-30s%9d
", "Object:", SizeOfObject.sizeOf(new Object()));
        System.out.println();
        System.out.printf("%-30s%9d
", "include one int:", SizeOfObject.sizeOf(new IntegerTestOne()));
        System.out.printf("%-30s%9d
", "include two int:", SizeOfObject.sizeOf(new IntegerTestTwo()));
        System.out.printf("%-30s%9d
", "include three int:", SizeOfObject.sizeOf(new IntegerTestThree()));
        System.out.println();
        System.out.printf("%-30s%9d
", "include one object:", SizeOfObject.sizeOf(new ReferenceTestOne()));
        System.out.printf("%-30s%9d
", "include one object:", SizeOfObject.sizeOf(new ReferenceTestTwo()));
    }

    public static void main(String[] args) {
        test2();
    }

    static class IntegerTestOne {
        private int i1 = 1;
    }

    static class IntegerTestTwo {
        private int i1 = 1;
        private int i2 = 1;
    }

    static class IntegerTestThree {
        private int i1 = 1;
        private int i2 = 1;
        private int i3 = 1;
    }

    static class ReferenceTestOne {
        private Object o1 = new Object();
    }

    static class ReferenceTestTwo {
        private Object o1 = new Object();
        private Object o2 = new Object();
    }
}
一些概念

對象內(nèi)存 = 對象頭 + 類型指針 + 對齊填充

對象頭不參與指針壓縮,并且 32 位時(shí)為 4 個(gè)字節(jié),64 位時(shí)為 8 個(gè)字節(jié)

類型指針參與指針壓縮,并且 32 位時(shí)為 4 個(gè)字節(jié),64 位時(shí)為 8 個(gè)字節(jié);指針壓縮時(shí) 64 位為 4 個(gè)字節(jié)

對齊填充,由于 jvm 設(shè)計(jì)內(nèi)存要為 8 字節(jié)的整數(shù)倍,所以不足的需要填充。如 對象頭和類型指針一共 12 字節(jié),填充后為 16 字節(jié),填充了 4 個(gè)字節(jié)

測試結(jié)果驗(yàn)證上面的假設(shè)

其中 (8 + 8) 為對象頭和類型指針的字節(jié)數(shù)

64 位 -XX:-UseCompressedOops -XX:+UseCompressedOops
Object 8 + 8 = 16 (對象頭+類型指針) 8 + 4 + 4 = 16(對象頭+壓縮的類型指針+對齊填充)
包含一個(gè)int (8 + 8) + 4 + 4 = 24 (8 + 4) + 4 = 16
包含兩個(gè)int (8 + 8) + 4*2 = 24 (8 + 4) + 4*2 + 4 = 24
包含三個(gè)int (8 + 8) + 4*3 + 4 = 32 (8 + 4) + 4*3 = 24
不壓縮引用占 8 個(gè)字節(jié),壓縮占 4 個(gè)字節(jié)
包含一個(gè)引用 (8 + 8) + 8 = 24 (8 + 4) + 4 = 16
包含兩個(gè)引用 (8 + 8) + 8*2 = 32 (8 + 4) + 4*2 + 4 = 24
靜態(tài)數(shù)據(jù)不在對象內(nèi)存里面
public class MemoryStaticTest {
    /**
     * -javaagent:{jar包路徑}SizeOfObject.jar
     * 使用指針壓縮,在一定情況下64位HotSpot jvm默認(rèn)指針壓縮
     *
     * Output:
     * amd64    +UseCompressedOops
     * StaticTest:                          16
     * Integer:                             16
     * StaticReferenceTest:                 16
     *
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(System.getProperty("os.arch") + "    +UseCompressedOops");
        System.out.printf("%-30s%9d
", "StaticTest:", SizeOfObject.sizeOf(new StaticTest()));
        System.out.printf("%-30s%9d
", "Integer:", SizeOfObject.sizeOf(new Integer(1)));
        System.out.printf("%-30s%9d
", "StaticReferenceTest:", SizeOfObject.sizeOf(new StaticReferenceTest()));
    }

    static class StaticTest {
        private static int i1 = 1;
        private static int i2 = 1;
        private static int i3 = 1;
        private static int i4 = 1;
        private static int i5 = 1;
        private static int i6 = 1;
    }

    static class StaticReferenceTest {
        private static Object o1 = new Object();
        private static Object o2 = new Object();
        private static Object o3 = new Object();
        private static Object o4 = new Object();
        private static Object o5 = new Object();

    }
}

代碼中還有一點(diǎn)其他測試: https://github.com/Deeeeeeeee/jcoding.git

為什么是這個(gè)樣子呢

對象頭在 64 位的時(shí)候,為什么是 8 個(gè)字節(jié);32 位的時(shí)候,為什么是 4 個(gè)字節(jié)

一個(gè)引用在 64 位的時(shí)候,為什么是 8 個(gè)字節(jié);32 位的時(shí)候,為什么是 4 個(gè)字節(jié)

這個(gè)跟 C++ 指針有關(guān)了,跟寄存器有關(guān)了

指針壓縮又是怎么個(gè)回事

這一切都可以在 jvm 的實(shí)現(xiàn)中找到答案,也就是看 C++ 代碼。只是我還沒到這個(gè)階段=。=

參考鏈接

【Java對象解析】不得不了解的對象頭

JDK從6 update 23開始在64位系統(tǒng)上會默認(rèn)開啟壓縮指針

【Java JVM】 Hotspot GC研究- 64位引用指針壓縮技術(shù)

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70798.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)存占用這里分析一個(gè)只有一組鍵值對的結(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
  • Java對象內(nèi)存布局解析

    摘要:堆內(nèi)存用于存放我們在程序中創(chuàng)建的對象,一旦沒有足夠的空間用于存放這些對象,即會拋出異常。當(dāng)我們采用后一種方式時(shí),我們需要了解一個(gè)對象是如何占據(jù)堆內(nèi)存空間的,或者說是了解一個(gè)對象是由哪些部分組成的。 JVM將內(nèi)存劃分為程序計(jì)數(shù)器(Program Counter Register)、虛擬機(jī)棧(VM Stack)、本地方法棧(Native Method Stack)、堆(Heap)以及方法區(qū)...

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

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

    zorro 評論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ōu)化之性能調(diào)優(yōu)常用參數(shù)設(shè)置

    摘要:作用默認(rèn),即,適當(dāng)調(diào)整年輕代大小,可以一定層度上較少出現(xiàn)的概率其余性能調(diào)優(yōu)常用參數(shù)設(shè)置指定的初始和最大堆內(nèi)存大小,兩值可以設(shè)置相同,以避免每次垃圾回收完成后重新分配內(nèi)存。 Java性能優(yōu)化之針對分代垃圾回收調(diào)整 [TOC] JVM內(nèi)存的系統(tǒng)級的調(diào)優(yōu)主要的目的是減少M(fèi)inor GC的頻率和Full GC的次數(shù),過多的Minor GC和Full GC是會占用很多的系統(tǒng)資源,影響系統(tǒng)的吞吐...

    Jrain 評論0 收藏0
  • Java GC

    摘要:對字節(jié)碼文件進(jìn)行解釋執(zhí)行,把字節(jié)碼翻譯成相關(guān)平臺上的機(jī)器指令。使用命令可對字節(jié)碼文件以及配置文件進(jìn)行打包可對一個(gè)由多個(gè)字節(jié)碼文件和配置文件等資源文件構(gòu)成的項(xiàng)目進(jìn)行打包。和不存在永久代這種說法。 Java技術(shù)體系 從廣義上講,Clojure、JRuby、Groovy等運(yùn)行于Java虛擬機(jī)上的語言及其相關(guān)的程序都屬于Java技術(shù)體系中的一員。如果僅從傳統(tǒng)意義上來看,Sun官方所定義的Jav...

    justCoding 評論0 收藏0

發(fā)表評論

0條評論

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