1).对象大小可以用jol­core包查看,引入依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.openjdk.jol</groupId>
    4. <artifactId>jol-core</artifactId>
    5. <version>0.9</version>
    6. </dependency>
    7. </dependencies>
    1. package com.tuling.jvm;
    2. import org.openjdk.jol.info.ClassLayout;
    3. /**
    4. * 计算对象大小
    5. */
    6. public class JOLSample {
    7. public static void main(String[] args) {
    8. ClassLayout layout = ClassLayout.parseInstance(new Object());
    9. System.out.println(layout.toPrintable());
    10. System.out.println();
    11. ClassLayout layout1 = ClassLayout.parseInstance(new int[]{});
    12. System.out.println(layout1.toPrintable());
    13. System.out.println();
    14. ClassLayout layout2 = ClassLayout.parseInstance(new A());
    15. System.out.println(layout2.toPrintable());
    16. }
    17. // ‐XX:+UseCompressedOops 默认开启的压缩所有指针
    18. // ‐XX:+UseCompressedClassPointers 默认开启的压缩对象头里的类型指针Klass Pointer
    19. // Oops : Ordinary Object Pointers
    20. public static class A {
    21. //8B mark word
    22. //4B Klass Pointer 如果关闭压缩‐XX:‐UseCompressedClassPointers或‐XX:‐UseCompressedOops,则占用8B
    23. int id; //4B
    24. String name; //4B 如果关闭压缩‐XX:‐UseCompressedOops,则占用8B
    25. byte b; //1B
    26. Object o; //4B 如果关闭压缩‐XX:‐UseCompressedOops,则占用8B
    27. }
    28. }

    image.png
    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.