Don’t Cross 32 GB!

栏目: Java · 发布时间: 5年前

看elasticsearch官方文档时,提到的一个观点: Don’t Cross 32 GB 。是因为当JVM堆少于32G时,HotSpot虚拟机会启用一个压缩对象指针。而如果超过32G,这个压缩对象指针就会失效。那么,纠结这个临界值的精确值是多大呢?开启压缩指针相比没有开启,能节省多少内存呢?让我们一探究竟!

Don’t Cross 32 GB!

Java 的世界里,绝大部分对象分配在堆里,并且被一个指针引用(Student stu = new Student(),new的这个Student对象就是分配在堆里,stu就是持有这个对象的引用)。

32位的操作系统,最大只支持4G内存(即2^32)。当然,对于当下来说,32位服务器应该是绝种了,所以本文讨论的是64位操作系统。对于64位操作系统来说,理论上分配的堆可以非常非常大。但是,64位指针的开销就意味着有更多的浪费空间,这仅仅是因为指针更大。比浪费空间更糟糕的是,64位指针在主内存和多级缓存之间移动数据的时候,还会消费更多的带宽。

Don’t Cross 32 GB!

Java用" compressed oops "术解决了这个问题,指针不再是指向内存中精确位置,,而是对象的偏移量(原文: Instead of pointing at exact byte locations in memory, the pointers reference object offsets )。这就意味着,32位指针能引用2^32个对象(大约43亿个对象),而不是引用总计2^32个字节大小对象。所以,堆大小直到32G左右还能保持32位指针。

一旦你越过这个32G -- 一个具有魔法般的数值。指针将切回到普通的对象指针。每个指针变大,意味着需要更多的CPU,内存和带宽,真正用来保持对象的内存就会更少。这就可能导致一种奇怪的现象,使用compressed oops的32G的堆和40~50G没有使用compressed oops的堆保存的对象数量是一样的。

这个事实告诉我们:即使你有多余的内存,也应该尽量避免超过32G这个界限。它会浪费内存,降低CPU性能,并且大堆情况下GC表现也一般般。更麻烦的是,那么大的堆,DUMP分析将是一件极其痛苦,极其麻烦的事情。相信我,你一定不想碰到那种局面。

应该设置多大?

32G是个近似值,这个临界值跟JVM和平台有关。如果不想精确设置的话,31G是个决定安全的数值,31G肯定默认开启compressed oops。我们可以通过增加JVM参数 -XX:+PrintFlagsFinal ,验证 UseCompressedOops 的值,从而得知,到底是不是真的开启了压缩指针,还是压缩指针失效!

实践才是检验真理的唯一标准!JUST DO IT!让我们动手验证这个临界值吧!

验证情况 -- JDK8前提下,32760m的堆是开启压缩指针的,32770m的堆压缩指针已经关闭:

[afei@afei ~]$ java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

[afei@afei ~]$ java -Xmx32760m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
     bool UseCompressedOops                        := true                                {lp64_product}
[afei@afei ~]$ java -Xmx32770m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
     bool UseCompressedOops                         = false                               {lp64_product}

32G,即32*1024=32768M,刚好在范围[32760, 32770]中。

土豪我有1T内存

JVM大堆的缺点太多了;

  • 超过32G压缩指针失效;

  • DUMP分析将是灾难;

  • 堆越大,GC表现越差;

总之,不要尝试吃这个螃蟹!那如果我是在一家有钱任性的公司,服务器牛逼的不要不要的,都是128G起步!毕竟不要让贫穷限制了想象!

这种情况下,我有小建议: 开多个32G的JVM实例 。4个32G的JVM实例绝对比1个128G实例表现要好。

简单测试验证

笔者做了一个简单测试,验证一下这个问题:分配设置Xmx为 Xmx32760mXmx32770m ,Xmn都是100M(S0:S1:Eden默认1:1:8)。总结分配一个包含8个对象类型和8个原子类型以及String,总计17个类型属性的对象1kw次。看它们分别触发了多少YGC,结论如下表所示:

实验次数 开启压缩指针YGC次数 关闭压缩指针YGC次数
1 17.53 21.91
2 17.54 21.92
3 17.52 21.94

由执行结果可知,Young区完全一样的情况下,开启压缩指针相比关闭压缩指针,能节省20%多的内存。由此可知, 32G还真是一个奇妙的魔法数值 !另外需要说明的是YGC次数有小数,是表示Eden区占用比例,比如17.52次YGC表示发生了17次YGC并且Eden还占了52%。

执行的命令:

java -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xmx32770m -Xms32770m -Xmn100m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly Test

说明: -Xmx32760m -Xms32760m 即表示开启压缩指针; -Xmx32770m -Xms32770m 即表示关闭压缩指针。

  • 附:测试源码

/**
 * @author afei
 * @date 2018-09-05
 * @since 1.0.0
 */
class Student{
    private byte a;
    private short b;
    private int c;
    private long d;
    private float e;
    private double f;
    private boolean g;
    private char h;

    private Byte i;
    private Short j;
    private Integer k;
    private Long l;
    private Float m;
    private Double n;
    private Boolean o;
    private Character p;

    private String q;

    // 省略带参数构造方法
}
public class Test {

    public static void main(String[] args) throws Exception{

        for (int i = 0; i < 10000000; i++) {
            Student stu = new Student(
                    (byte)(i%128), (short)(i%256), i, i, i, i, i%2==0?true:false, 'a',
                    (byte)(i%128), (short)(i%256), i, (long)i, (float)i, (double)i, 
                    i%2==0?Boolean.TRUE:Boolean.FALSE, 'a', String.valueOf(i));
            if(i>0 && i%100000==0){
                System.out.println("i="+i);
            }
        }
        // 留点时间采集GC信息
        Thread.sleep(20000);
    }
}

参考:https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html

Don’t Cross 32 GB!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML5

HTML5

Matthew David / Focal Press / 2010-07-29 / USD 39.95

Implement the powerful new multimedia and interactive capabilities offered by HTML5, including style control tools, illustration tools, video, audio, and rich media solutions. Understand how HTML5 is ......一起来看看 《HTML5》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具