欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java new一个Object占多少字节

程序员文章站 2022-03-06 10:00:50
...

Java new一个空Object所占内存大小

使用OpenJDK提供的jol(Java Object Layout)库进行观察。
Maven引入依赖:

<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.10</version>
</dependency>

测试代码:

Object o = new Object();
String layout = ClassLayout.parseInstance(o).toPrintable();
System.out.println(layout);

输出:

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e5 01 00 20 (11100101 00000001 00000000 00100000) (536871397)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

实例对象占用16个字节。

Java new一个Object占多少字节

Java对象的内容:

Java new一个Object占多少字节

MarkWord:32/64位虚拟机,对应长度为32/64bit;

  1. 主要用来表示对象的线程锁状态,另外还可以用来配合GC、存放该对象的hashCode;

KlassWord: 32/64位虚拟机,对应长度为32/64bit;(默认开启指针压缩,64位长度为32bit

  1. 这一部分用于存储对象的类型指针,该指针指向它的类元数据,JVM通过这个指针确定对象是哪个类的实例。该指针的位长度为JVM的一个字大小,即32位的JVM为32位,64位的JVM为64位。
  2. 如果应用的对象过多,使用64位的指针将浪费大量内存,统计而言,64位的JVM将会比32位的JVM多耗费50%的内存。为了节约内存可以使用选项+UseCompressedOops开启指针压缩,其中,oop即ordinary object pointer普通对象指针。开启该选项后,下列指针将压缩至32位:
    1)每个Class的属性指针(即静态变量)
    2)每个对象的属性指针(即对象变量)
    3)普通对象数组的每个元素指针
    4)当然,也不是所有的指针都会压缩,一些特殊类型的指针JVM不会优化,比如指向PermGen的Class对象指针(JDK8中指向元空间的Class对象指针)、本地变量、堆栈元素、入参、返回值和NULL指针等。

数组长度

如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,这部分数据的长度也随着JVM架构的不同而不同:32位的JVM上,长度为32位;64位JVM则为64位。64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位。