java 64 位的指针压缩_java对象的存储结构和指针压缩学习

在HotSpot虚拟机里,对象在堆内存中的存储不惧可以划分为三个部分:

对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

对象头:包含了Mark Word(一定存在),元数据指针(一定存在),数组size(如果这个对象是个数组对象的话)。

实例数据:类元信息中定义的变量数据

对齐填充:可能存在的部分,同对象头一样,为了8字节对齐的无实际意义填充部分。

64位虚拟机来说,低于32G内存,默认开启指针压缩,那么堆中的对象是这样子的。

82a2ef7efecc2151a0a4a7fce79a11ea.png

可以使用jol包来观察对象的存储结构,引入pom文件

org.openjdk.jol

jol-core

0.10

1)查看对象内部信息:ClassLayout.parseInstance(obj).toPrintable()

2)查看对象占用空间总大小:GraphLayout.parseInstance(obj).totalSize() 一个空的Object对象,64位虚拟机打开指针压缩(默认开启或者VM -options设置下  -XX:+UseCompressedOops开启)

3)测试

package com.test.demo.test.jvm;

import org.openjdk.jol.info.ClassLayout;

import org.openjdk.jol.info.GraphLayout;/**

* @program: demo

* @description: 查看对象内存 空对象一般16b(没有普通属性的类生成的对象)

* -XX:+UseCompressedOops开启指针压缩(默认) oop对象指针

* -XX:-UseCompressedOops关闭指针压缩

* 指针压缩的原理:

* 指针不再表示对象在内存中的精确位置,而是表示偏移量。这意味着32位的指针可以引用40亿个对象,

* 而不是40亿个字节。最终,也就是说内存增长到32GB的物理内存,也可以用32位的指针表示。也就是说,我们只需要

* 知道JVM内存的开始位置,知道偏移量,就可以算出我想要找的实际物理位置。

---------------对象头区域-----------实例数据区域---------对齐填充区域(保证8的倍数)

markword( 32位 4byte ---64位 8byte)

class指针(开启指针压缩 4byte 关闭 8byte)

数组对象(开启指针压缩 4byte 关闭 8byte)

* @author: zhugaopo

* @slogan: 致敬大师、致敬未来的你.

* @create: 2020-07-16 10:17*/

public classCountObjectSize {int a = 10;

int b = 20;

String[] aa =new String[]{"a","b","c"};public static voidmain(String[] args) {

Objectobject = newObject();

String s1= ClassLayout.parseInstance(object).toPrintable();

System.out.println("空对象"+s1);//空Object 开启指针压缩: markword 8bytes + class地址 4bytes + 成员变量 0bytes + 对齐填充 4bytes = 16bytes//空Object 关闭指针压缩: markword 8bytes + class地址 8bytes + 成员变量 0bytes + 对齐填充 0bytes = 16bytes

CountObjectSize countObjectSize = newCountObjectSize();

String s=ClassLayout.parseInstance(countObjectSize).toPrintable();

System.out.println(s);//非空Object 开启指针压缩: markword 8bytes + class地址 4bytes + 成员变量 4 + 4 + 4 bytes + 对齐填充 0bytes = 24bytes//非空Object 关闭指针压缩: markword 8bytes + class地址 8bytes + 成员变量 4 + 4 + 8 bytes + 对齐填充 0bytes = 32bytes//数组对象在关闭指针压缩的情况下 8byte 开启4byte//开启指针压缩,提升jvm运行效率

long l =GraphLayout.parseInstance(countObjectSize).totalSize();

System.out.println(l);

}

}

输出:

1、空对象开启/关闭指针压缩:

空Object 开启指针压缩: markword 8bytes + class指针 4bytes + 成员变量 0bytes + 对齐填充 4bytes = 16bytes

316b61432bcde1dae569ed9c7ec6adfe.png

空Object 关闭指针压缩: markword 8bytes + class指针 8bytes + 成员变量 0bytes + 对齐填充 0bytes = 16bytes

48b2af5ae67c5f767b68281cf3f5df68.png

2、包含数组的对象开启/关闭指针压缩:

开启指针压缩: markword 8bytes + class指针 4bytes + 成员变量 0bytes + 对齐填充 4bytes = 16bytes

aa77d1c7202f078c838573dac0342eb8.png

关闭指针压缩: markword 8bytes + class指针 8bytes + 成员变量 0bytes + 对齐填充 0bytes = 16bytes

d703bf4a3a44e933c8ee0e4f67dcd752.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值