java对象大小及浅堆、深堆、保留内存的概念

以下所有数据均为64位环境下。

java对象大小由以下几部分组成:对象头 + 实例数据 + 对齐填充 。

对象头

对象头 = 标记部分(mark word) + 原始对象引用

标记部分记录了该对应的运行时数据,如hashCode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分大小在32位机器上为4byte,64位机器上为8byte。

原始对象引用就是对象的指针,通过这个指针找到对象的实例,该数据可以压缩。这部分大小在32位机器上为4byte,在64位机器上为8byte,如果开启了压缩(UseCompressedOops),大小为4byte。jdk8默认开启压缩。

由上述概念可知,一个对象头的大小 = 标记部分(8byte) + 原始对象引用(未压缩:8byte/压缩:4byte)=未压缩:16byte/压缩:12byte。

实例数据

原始数据大小

类型大小(单位:byte)
byte1
boolean1
char2
short2
int4
float4
double8
long8

 

 

对象引用大小为32位 4byte,64位8byte(开启压缩后为4byte)。

对齐填充

对齐填充说的是任何对象都用8byte来对齐,所以对象的大小为8的整数倍。

所以一个没有任何参数的控对象,对象大小为16byte。

浅堆

浅堆大小为对象本身的大小,浅堆大小 = 对象头 + 实例数据 + 对齐填充

深堆

深堆大小是对象所涉及的所有对象的大小之和。

保留内存

保留内存是指只能通过该对象访问的对象浅堆之和。

举例:假设5个对象:A,B,C,D,E。A引用B和C,D引用C和E

A的深堆大小 = A + B + C

A的保留内存大小 = A + B,因为D引用了C。

保留内存为对象回收后,肯定释放的内存,上述例子中,回收A,肯定会回收B,但是不会回收C,因为D引用了C。

实例代码:

package com.test

public class Test {

    A a = new A();

    B b = new B();

    public static void main(String[] args) throws Exception {
        Test t = new Test();
        System.in.read();
    }
}

class A {

    private String a = "a";

    private byte[] b = new byte[1024 * 2];
}

class B {
    private double d = 2D;
}

使用 jmap -dump获得程序的内存快照,在mat(MyEclipse Memory Analyzer tools)中打开,找到com.test.Test类,查看浅堆,深堆(Retained Heap虽然字面上是保留内存,但是实际是指的深堆)大小。

开启压缩,图如下:

可以看到com.test.Test的浅堆大小为24byte,深堆大小为2184byte。

根据代码分析com.test.Test对象浅堆大小 = 对象头(12byte)+ A引用(4byte) + B引用(4byte)+ 对齐填充(4byte) = 24byte

com.test.A对象浅堆大小 = 对象头(12byte) + 字符串a引用(4byte)+ 数组引用(4byte)+ 对齐填充(4byte)=24byte

com.test.B对象浅堆大小 = 对象头(12byte)+ 基本类型double变量(8byte)+ 对齐填充(4byte)= 24byte

byte数组b浅堆大小 = 对象头(12byte)+ 2048 * 基本类型byte的大小 = 12 + 2048 = 2064byte

String类中包含两个参数int类型的hash 和 char数组,所以String类型的a也占24byte。

转载于:https://my.oschina.net/aidelingyu/blog/1602341

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值