1).对象大小可以用jolcore包查看,引入依赖
<dependencies><dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version></dependency></dependencies>
package com.tuling.jvm;import org.openjdk.jol.info.ClassLayout;/*** 计算对象大小*/public class JOLSample {public static void main(String[] args) {ClassLayout layout = ClassLayout.parseInstance(new Object());System.out.println(layout.toPrintable());System.out.println();ClassLayout layout1 = ClassLayout.parseInstance(new int[]{});System.out.println(layout1.toPrintable());System.out.println();ClassLayout layout2 = ClassLayout.parseInstance(new A());System.out.println(layout2.toPrintable());}// ‐XX:+UseCompressedOops 默认开启的压缩所有指针// ‐XX:+UseCompressedClassPointers 默认开启的压缩对象头里的类型指针Klass Pointer// Oops : Ordinary Object Pointerspublic static class A {//8B mark word//4B Klass Pointer 如果关闭压缩‐XX:‐UseCompressedClassPointers或‐XX:‐UseCompressedOops,则占用8Bint id; //4BString name; //4B 如果关闭压缩‐XX:‐UseCompressedOops,则占用8Bbyte b; //1BObject o; //4B 如果关闭压缩‐XX:‐UseCompressedOops,则占用8B}}

2).指针压缩
1.jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩
2.jvm配置参数:UseCompressedOops,compressed压缩、oop(ordinary object pointer)对象指针
3.启用指针压缩:XX:+UseCompressedOops(默认开启),禁止指针压缩:XX:UseCompressedOops
为什么要进行指针压缩?
1.在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据, 占用较大宽带,同时GC也会承受较大压力
2.为了减少64位平台下内存的消耗,启用指针压缩功能,由上图可以看出,没启用压缩是用8B进行存取的,压缩后是用4B进行存取的。
3.在jvm中,32位地址最大支持4G内存(2的32次方),可以通过对对象指针的压缩编码、解码方式进行优化,使得jvm 只用32位地址就可以支持更大的内存配置(小于等于32G)
4.堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间
5.堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好
6.如果服务器内存大于32位的时候,目前JDK是不提供指针压缩的,会用8B进行存取,对服务器的宽带和GC会有较大的压力,所以建议服务器的内存不要超过32G,一般互联网公司服务器的内存也不会特别大,一般都不会超过32G.
