🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 如何计算对象大小 1. 搞清楚Java对象的布局结构 2. 借助`jol-core`包来打印对象 3. 引用的指针压缩 ## 对象布局 ![](https://img.kancloud.cn/ce/c1/cec1a91e96673b1c679c0b6562b621f8_1938x1098.png) ## Java对象布局(Java Object Layout) ### String对象例子 ![](https://img.kancloud.cn/5e/35/5e356e34a9e40ad15625d059b97b2a4b_3664x844.png) ### int[]数组对象例子 ![](https://img.kancloud.cn/04/21/042133c524d818fb5327b9647c812b7b_3716x1484.png) ## 引用的指针压缩 ### JVM内存寻址最大内存是多少? ~~~ // 打印jvm的详细信息 System.out.println(VM.current().details()); ~~~ ``` # Running 64-bit HotSpot VM. // 64位hotSpot虚拟机 # Using compressed oop with 3-bit shift. // 对象压缩 3位无符号右移 # Using compressed klass with 3-bit shift. // 类型指针压缩 3为无符号右移 # Objects are 8 bytes aligned. // 对象按8字节对齐 ``` 对象按8字节对齐,且jvm的引用占4个字节,能表示2^32=4G * 8 = 32G的物理内存。 ![](https://img.kancloud.cn/63/af/63afe676ba86ed88ec44e989693c5337_1780x758.png) ### 不启用指针压缩 采用8字节(64位)存储真实内存地址,比之前采用4字节(32位)压缩存储地址带来的问题: 1. 增加了GC开销:64位对象引用需要占用更多的堆空间,留给其他数据的空间将会减少,从而加快了GC的发生,更频繁的进行GC。 2. 降低CPU缓存命中率:64位对象引用增大了,CPU能缓存的oop将会更少,从而降低了CPU缓存的效率。 ### 启用指针压缩 * `-XX:+UseCompressedOops` 开启指针压缩,jdk6之后默认开启。 * `-XX:+PrintFlagsFinal` 打印jvm参数,可以用来验证检查环境内的参数配置生效情况。 * 内存大于32GB时,开启指针压缩的参数会失效! ## 总结 对象大小 = 对象头字节 + 实例数据字节 + 填充字节 ## 参考资料 * 周志明 * 《深入理解Java虚拟机》