编程语言
首页 > 编程语言> > JVM中裸java.lang.Object的实际大小

JVM中裸java.lang.Object的实际大小

作者:互联网

根据Memory usage of Java objects: general guide

在热点中:

a normal object requires 8 bytes of “housekeeping” space;

arrays require 12 bytes (the same as a normal object, plus 4 bytes for the array length).

对象大小粒度

In Hotspot, every object occupies a number of bytes that is a multiple
of 8. If the number of bytes required by an object for its header and
fields is not a multiple 8, then you round up to the next multiple of
8.

This means, for example, that:

>裸对象占用8个字节;
>具有单个布尔字段的类的实例占用16个字节:8个字节的标头,1个字节的布尔值和7个字节的“填充”,以使大小最大为8的倍数;
>具有八个布尔字段的实例也将占用16个字节:

> 8表示标头,8表示布尔值;因为这已经是8的倍数,所以不需要填充;

>具有两个长字段,三个int字段和一个布尔值的对象将占用:

标头> 8个字节;
> 2个long的16个字节(每个8个);
> 3个int的12个字节(每个4个);
布尔值> 1个字节;
>再加上3个字节的填充,将总数从37舍入到40,是8的倍数.

我的问题:

裸露的java.lang.Object没有字段.因此,新的Ojbect()将占用8字节的堆空间.

但是当我通过使用 instrumentation agent util测试新Object()的大小时.

System.out.println(MemoryUtil.deepMemoryUsageOf(new Object()));

结果是16,而不是8.有人可以告诉我为什么吗?

编辑:

据我所知,x86上the object header的大小为4byte.

对象标头还包含用于同步的锁定信息.

//  32 bits:
//  --------
//      hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
//      JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
//      size:32 ------------------------------------------>| (CMS free block)
//      PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)

因此,对象的开销为4byte(对象标头)4byte(类指针)= 8byte.

解决方法:

这个interesting presentation可能会给您带来更多的见解.

基本上,由于在64位JVM中内存对齐和填充为8个字节,因此对象开销为16个字节:每个属性(标头和类引用)占用8个字节.请参阅演示文稿中的幻灯片38.但是请注意,使用JVM选项-XX:UseCompressedOops时,开销减少到12个字节.

标签:jvm,memory-management,java
来源: https://codeday.me/bug/20191122/2057779.html