JAVA对象大小的获取

1. Java 对象的内存布局

Java的实例对象、数组对象在内存中的组成包括如下三部分:对象头Hearder、实例数据、内存填充。示意图如下所示
在这里插入图片描述

  • 对象头
    其主要包括两部分数据:Mark Word、Class对象指针。特别地对于数组对象而言,其还包括了数组长度数据。在64位的HotSpot虚拟机下,Mark Word占8个字节,其记录了Hash Code、GC信息、锁信息等相关信息;而Class对象指针则指向该实例的Class对象,在开启指针压缩的情况下占用4个字节,否则占8个字节;如果其是一个数组对象,则还需要4个字节用于记录数组长度信息。这里列出64位HotSpot虚拟机Mark Word的具体含义,以供参考。需要注意的是在下图的Mark Word中,左侧为高字节,右侧为低字节
    在这里插入图片描述

  • 实例数据
    用于存放该对象的实例数据

  • 内存填充
    64位的HotSpot要求Java对象地址按8字节对齐,即每个对象所占内存的字节数必须是8字节的整数倍。因此Java对象需要通过内存填充来满足对齐要求

注:

在64位的HotSpot虚拟机下,类型指针、引用类型需要占8个字节。显然这大大增加了内存的消耗和占用。为此从JDK 1.6开始,64位的JVM支持UseCompressedOops选项。其可对OOP(Ordinary Object Pointer,普通对象指针)进行压缩,使其只占用4个字节,以达到节约内存的目的。在JDK 8下,该选项默认启用。当然也可以通过添加JVM参数来显式进行配置

-XX:+UseCompressedOops  // 开启指针压缩
-XX:-UseCompressedOops  // 关闭指针压缩

2. 代码示例获取Java对象的大小

引入maven依赖

<dependency>
   <groupId>org.openjdk.jol</groupId>
   <artifactId>jol-core</artifactId>
   <version>0.17</version>
   <scope>compile</scope>
</dependency>

2.1 基本类型的大小

package com.zishi.jvm.jol.ab;
public class A {
    boolean bo1;
    boolean bo2;
    byte b1;
    byte b2;
    char c1;
    char c2;
    double d1;
    double d2;
    float f1;
    float f2;
    int i1;
    int i2;
    long l1;
    long l2;
    short s1;
    short s2;
}
public static void main(String[] args) {
	System.out.println(ClassLayout.parseClass(A.class).toPrintable());
}

关闭压缩的结果如下:

com.zishi.jvm.jol.ab.A object internals:
OFF  SZ      TYPE DESCRIPTION               VALUE
  0   8           (object header: mark)     N/A
  8   8           (object header: class)    N/A  -- 这里占了8个字节
 16   8    double A.d1                      N/A
 24   8    double A.d2                      N/A
 32   8      long A.l1                      N/A
 40   8      long A.l2                      N/A
 48   4     float A.f1                      N/A
 52   4     float A.f2                      N/A
 56   4       int A.i1                      N/A
 60   4       int A.i2                      N/A
 64   2      char A.c1                      N/A
 66   2      char A.c2                      N/A
 68   2     short A.s1                      N/A
 70   2     short A.s2                      N/A
 72   1   boolean A.bo1                     N/A
 73   1   boolean A.bo2                     N/A
 74   1      byte A.b1                      N/A
 75   1      byte A.b2                      N/A
 76   4           (object alignment gap)    -- 对齐了4个字节
Instance size: 80 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

开启压缩的结果如下:

com.zishi.jvm.jol.ab.A object internals:
OFF  SZ      TYPE DESCRIPTION               VALUE
  0   8           (object header: mark)     N/A
  8   4           (object header: class)    N/A  -- 这里占了4个字节
 12   4     float A.f1                      N/A
 16   8    double A.d1                      N/A
 24   8    double A.d2                      N/A
 32   8      long A.l1                      N/A
 40   8      long A.l2                      N/A
 48   4     float A.f2                      N/A
 52   4       int A.i1                      N/A
 56   4       int A.i2                      N/A
 60   2      char A.c1                      N/A
 62   2      char A.c2                      N/A
 64   2     short A.s1                      N/A
 66   2     short A.s2                      N/A
 68   1   boolean A.bo1                     N/A
 69   1   boolean A.bo2                     N/A
 70   1      byte A.b1                      N/A
 71   1      byte A.b2                      N/A
Instance size: 72 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

注:以下代码均开启压缩

2.2 包装类型的大小

public class B {
    Boolean bo1;
    Byte b1;
    Character c1;
    Double d1;
    Float f1;
    Integer i1;
    Long l1;
    Short s1;
}

结果如下:

com.zishi.jvm.jol.ab.B object internals:
OFF  SZ                  TYPE DESCRIPTION               VALUE
  0   8                       (object header: mark)     N/A
  8   4                       (object header: class)    N/A
 12   4     java.lang.Boolean B.bo1                     N/A
 16   4        java.lang.Byte B.b1                      N/A
 20   4   java.lang.Character B.c1                      N/A
 24   4      java.lang.Double B.d1                      N/A
 28   4       java.lang.Float B.f1                      N/A
 32   4     java.lang.Integer B.i1                      N/A
 36   4        java.lang.Long B.l1                      N/A
 40   4       java.lang.Short B.s1                      N/A
 44   4                       (object alignment gap)    
Instance size: 48 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

3.3 数组对象的大小(int[] 为例说明)

    public static void main(String[] args) {
        int[] array = new int[3];
        array[0] = 11;
        array[1] = 22;
        array[2] = 33;
        System.out.println( ClassLayout.parseInstance(array).toPrintable() );
    }

结果如下:

[I object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0) --对象头
  8   4        (object header: class)    0x00000c10 -- 对象字节头信息
 12   4        (array length)            3  --数组的长度
 16  12    int [I.<elements>             N/A -- 数组元素占的空间
 28   4        (object alignment gap)    -- 对齐
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

数组的对象头里面包含了数组的长度,占4个字节。

3.3 继承

public class GrandFather {

    private int age;

    protected double money;

    public double bbb;
}
public class Son extends Father {
    private double rrr;
}
public class Father extends GrandFather {

    protected double money;
    protected double ddd;
}

main方法:

public static void main(String[] args) {

    System.out.println(ClassLayout.parseClass(GrandFather.class).toPrintable());
    System.out.println("-----------------------------------------------------------------");
    System.out.println(ClassLayout.parseClass(Father.class).toPrintable());
    System.out.println("-----------------------------------------------------------------");
    System.out.println(ClassLayout.parseClass(Son.class).toPrintable());
}
com.zishi.jvm.jol.ab.GrandFather object internals:
OFF  SZ     TYPE DESCRIPTION               VALUE
  0   8          (object header: mark)     N/A
  8   4          (object header: class)    N/A
 12   4      int GrandFather.age           N/A
 16   8   double GrandFather.money         N/A
 24   8   double GrandFather.bbb           N/A
Instance size: 32 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

-----------------------------------------------------------------
com.zishi.jvm.jol.ab.Father object internals:
OFF  SZ     TYPE DESCRIPTION               VALUE
  0   8          (object header: mark)     N/A
  8   4          (object header: class)    N/A
 12   4      int GrandFather.age           N/A
 16   8   double GrandFather.money         N/A
 24   8   double GrandFather.bbb           N/A
 32   8   double Father.money              N/A
 40   8   double Father.ddd                N/A
Instance size: 48 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

-----------------------------------------------------------------
com.zishi.jvm.jol.ab.Son object internals:
OFF  SZ     TYPE DESCRIPTION               VALUE
  0   8          (object header: mark)     N/A
  8   4          (object header: class)    N/A
 12   4      int GrandFather.age           N/A
 16   8   double GrandFather.money         N/A
 24   8   double GrandFather.bbb           N/A
 32   8   double Father.money              N/A
 40   8   double Father.ddd                N/A
 48   8   double Son.rrr                   N/A
Instance size: 56 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

3.4 异常

    public static void main(String[] args) {
        System.out.println(ClassLayout.parseClass(Throwable.class).toPrintable());
    }

结果如下:

java.lang.Throwable object internals:
OFF  SZ                            TYPE DESCRIPTION                      VALUE
  0   8                                 (object header: mark)            N/A
  8   4                                 (object header: class)           N/A
 12   4                java.lang.Object Throwable.backtrace              N/A
 16   4                java.lang.String Throwable.detailMessage          N/A
 20   4             java.lang.Throwable Throwable.cause                  N/A
 24   4   java.lang.StackTraceElement[] Throwable.stackTrace             N/A
 28   4                  java.util.List Throwable.suppressedExceptions   N/A
 32   4                             int Throwable.depth                  N/A
 36   4                                 (object alignment gap)           
Instance size: 40 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

3.5 Class

public static void main(String[] args) {
	System.out.println(ClassLayout.parseClass(Class.class).toPrintable());
}

结果如下:

java.lang.Class object internals:
OFF  SZ                                              TYPE DESCRIPTION                    VALUE
  0   8                                                   (object header: mark)          N/A
  8   4                                                   (object header: class)         N/A
 12   4                     java.lang.reflect.Constructor Class.cachedConstructor        N/A
 16   4                                   java.lang.Class Class.newInstanceCallerCache   N/A
 20   4                                  java.lang.String Class.name                     N/A
 24   4                                  java.lang.Module Class.module                   N/A
 28   4                                                   (alignment/padding gap)        
 32   4                                  java.lang.String Class.packageName              N/A
 36   4                                   java.lang.Class Class.componentType            N/A
 40   4                       java.lang.ref.SoftReference Class.reflectionData           N/A
 44   4   sun.reflect.generics.repository.ClassRepository Class.genericInfo              N/A
 48   4                                java.lang.Object[] Class.enumConstants            N/A
 52   4                                     java.util.Map Class.enumConstantDirectory    N/A
 56   4                    java.lang.Class.AnnotationData Class.annotationData           N/A
 60   4             sun.reflect.annotation.AnnotationType Class.annotationType           N/A
 64   4                java.lang.ClassValue.ClassValueMap Class.classValueMap            N/A
 68  28                                                   (alignment/padding gap)        
 96   4                                               int Class.classRedefinedCount      N/A
100   4                                                   (object alignment gap)         
Instance size: 104 bytes
Space losses: 32 bytes internal + 4 bytes external = 36 bytes total

3.6 注解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值