java指针压缩临界值

java指针压缩临界值

  • 一、概念
  • 二、代码
  • 三、测试
      • 1. 试试看32g
      • 2. 参照物来了,31g
      • 3. 32g - 1m = 32767m
      • 4. 没有什么是减1m不能解决的,如果有...
  • 四、最后

一、概念

  1. 在64位平台的HotSpot中使用32位指针,内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力
  2. 为了减少64位平台下内存的消耗,启用指针压缩功能
  3. 堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址

以上内容摘自ignorewho的博客。这里提到了32G这个临界值,那么,我们的程序应该设置多大的堆内存,才能恰好避开指针压缩失效,而且最大限度的使用内存呢?下面我们开始实验探索。

二、代码

测试程序的思路很简单。我们既然要测试的其实就是不同内存下引用的大小,单个引用是很小的,可以通过量级来减少误差。那么约束条件也就有了:

  1. 足够多的引用(即足够多的对象)
  2. 统计前不要发生gc

程序设计如下:

import java.util.LinkedList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        List<Integer> list = new LinkedList<>();
        int total = Integer.parseInt(args[0]) * 10000;
        for (int i = 0; i < total; i++) {
            list.add(i);
        }
        System.out.println(list.size());
        // 留给观察和截图的时间
        Thread.sleep(5000);
        // 维持一个引用
        System.out.println(list.size());
    }
}

三、测试

1. 试试看32g

执行命令java -Xms32g -Xmx32g -jar test-memory.jar 1000
java指针压缩临界值_第1张图片
可以看到,32g堆内存下,包含1000万个Integer元素的LinkedList共占用内存727.8MB。但此时我们并不知道jvm是否采用了指针压缩策略,因为我们缺少一个参照物。

2. 参照物来了,31g

执行命令java -Xms31g -Xmx31g -jar test-memory.jar 1000
java指针压缩临界值_第2张图片
果然如我们所料!内存只占用了495.5MB,整整下降了232.3MB!下降幅度达32%,但如果反过来说,从31g到32g,内存占用则上升了47%!当然,由于本例采用LinkedList,属于引用多但对象小,所以比正常的程序要更明显,但也足以说明问题了。所以我们目前的结论是,在堆内存32g整的时候,jvm的指针压缩就已经失效了
那么实验到这里就结束了?当然不。31g到32g之间还有整整1g、1024k、1048576b的内存,怎么可能就这么放弃了,我们继续。

3. 32g - 1m = 32767m

执行命令java -Xms332767m -Xmx332767m -jar test-memory.jar 1000
java指针压缩临界值_第3张图片
看到这个实验结果可能我们有些失望,32767m下占用的内存和32g下竟然如出一辙——727.8M。到这里我们可能有一些疑问了,不是说32g以上指针压缩才会失效吗,为什么32g-1m的情况下依然失效了?但换个思路,这也说明,实验进行到这里,我们已经不虚此行了,所谓的32g临界点,并不是一个确切的值
那么我们如何处理这种情况?还要1m这样递减下去吗?是的。哈哈,开个玩笑。但是由于一时没有太好的思路,我们倒不妨再试一次,如果结果再没有变化,我们再去探索其他的办法。

4. 没有什么是减1m不能解决的,如果有…

执行命令java -Xms332766m -Xmx332766m -jar test-memory.jar 1000
java指针压缩临界值_第4张图片
成了!可以看到,在332766m(32g - 2m)下,内存占用回到了498.8M,指针压缩又回来了!写到这里我懒得写了,就这样吧。希望小伙伴们可以亲自继续探索一下背后的奥秘,遇到困难可以留言或者私聊我~

四、最后

这篇博客不属于严格的技术博客,抛弃了jvm源码分析,也基本没有引用官方说明。它的目的和意义仅在于给初学者一个易懂易操作的示例流程,当然,如果能激发起继续探索的兴趣那就更好了。想要继续探索的小伙伴可以先看下这篇博客。

你可能感兴趣的:(java,jvm,指针压缩,Java)