Don’t Cross 32 GB!
看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位指针在主内存和多级缓存之间移动数据的时候,还会消费更多的带宽。
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 UseCompressedOopsbool UseCompressedOops := true {lp64_product}
[afei@afei ~]$ java -Xmx32770m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOopsbool UseCompressedOops = false {lp64_product}
32G,即32*1024=32768M,刚好在范围[32760, 32770]中。
土豪我有1T内存
JVM大堆的缺点太多了;
- 超过32G压缩指针失效;
- DUMP分析将是灾难;
- 堆越大,GC表现越差;
总之,不要尝试吃这个螃蟹!那如果我是在一家有钱任性的公司,服务器牛逼的不要不要的,都是128G起步!毕竟不要让贫穷限制了想象!
这种情况下,我有小建议:开多个32G的JVM实例。4个32G的JVM实例绝对比1个128G实例表现要好。
简单测试验证
笔者做了一个简单测试,验证一下这个问题:分配设置Xmx为Xmx32760m
和Xmx32770m
,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 wangzhenfei* @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!相关推荐
- elasticsearch优化总结
一. 硬件环境选择: 如果有条件,尽可能使用SSD硬盘, 不错的CPU.ES的厉害之处在于ES本身的分布式架构以及lucene的特性.IO的提升,会极大改进ES的速度和性能. 二.系统拓朴设计: ES ...
- 弃用 32 位!所有基于 IntelliJ 的 IDE 将不再支持 32 位操作系统
整理 | 苏宓 出品 | CSDN(ID:CSDNnews) 近日,JetBrain 宣布旗下所有基于 IntelliJ 的 IDE 将停止支持 32 位操作系统,其中包括 AppCode.Clion ...
- 32位/64位WIN2003各版本支持内存列表 彻底解决XP系统无法支持4G内存的问题
WIDOWS2003各版本支持内存简表 版本 支持CPU数量 支持最大内存 32位 Windows Server 2003, Standard Edition (标准版) 2路 4G 32 ...
- 配置 SQL Server 以便使用 2 GB 以上的物理内存
配置 SQL Server 以便使用 2 GB 以上的物理内存 [@more@]1. 概要 ??使用Windows 2000 Server 的操作系统,对于SQL Server而言,需要打开操作系统的 ...
- 32位系统的X86到底能支持多大内存
微软最新Windows Server 2008 R2 \ 以及最新的Microsoft Office SharePoint ( MOSS ) 2010 \ Project Server 2010 \ ...
- 读文章笔记-自适应和加速GB生成算法
读文章笔记-GBC 文章 背景 内容 定义1+现有GB生成过程 GBKNN 文章的GB生成算法 疑问与反思 文献脉络 文章 An Efficient and Adaptive Granular-Bal ...
- 戴尔(Dell)G3 3579(128 GB 固态硬盘+1 TB 机械硬盘)安装Ubuntu 16.04 LTS单系统(不是双系统,只装Ubuntu)
Table of Contents 硬件: 目标: 步骤: 1. 关于系统盘(在另外一台机子上操作U盘文件) 2. BIOS设置 3.安装系统 4. 安装完成后注意事项 5. 附安装过程中遇到的错误( ...
- NVIDIA GPUs上深度学习推荐模型的优化
NVIDIA GPUs上深度学习推荐模型的优化 Optimizing the Deep Learning Recommendation Model on NVIDIA GPUs 推荐系统帮助人在成倍增 ...
- Machine learning strategies for systems with invariance properties( 具有不变性系统的机器学习策略 )2016年Julia Ling
目录 摘要 1.介绍 2.方法 2.1不变基的结构 2.2建立机器学习模型 2.3机器学习算法 3.研究案例 3.1.湍流模型案例研究 3.1.1.问题阐述 3.1.2.不变性 3.1.3.数据集 3 ...
最新文章
- OpenStack Nova 高性能虚拟机之 CPU 绑定
- 【组合数学】指数生成函数 ( 指数生成函数求解多重集排列示例 )
- Java集合源码分析(二)ArrayList
- PhpMyAdmin导入数据库大小限制?
- java实现word邮件合并,Aspose.Words控件操作实例—邮件合并功能概述
- (6)段描述符D/B位
- 【网络安全】Penelope:一款功能强大的Shell处理工具
- vue 实现返回上一页不请求数据keep-alive
- ERROR org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: Exception in doCheckpoint
- 常用有话帧检测技术(VAD)
- C++定义隐式转换函数,将类转换为内部的一个成员变量
- Java编程思想 学习笔记1
- P1829 [国家集训队]Crash的数字表格(推了好久的mobius反演)
- Android 功耗优化(3)---Android后台调度与省电
- html无需列表怎么打,如何以html无序列表形式而不是xml打印这些结果?
- Python 下的 lambda 算子
- Java annotation 自定义注释@interface的用法 转载记录
- mysql 数据类型总结
- [书籍翻译]12周撰写期刊文章 学术出版成功指南——第 4 周:选择期刊
- 手机APP测试类型与方法
热门文章
- PHP 实现大数据(30w量级)表格导出(导出excel) 提高效率,减少内存消耗,终极解决方案
- 利用python re提取文件中的块内容(多行)
- unity沙子堆积_unity游戏逼真沙子和白雪粒子特效渲染创建插件Basic Sand amp; Snow 1.0 - 素材巷...
- Linux设置U盘加密,制作Kali Linux 加密U盘启动盘
- Go语言段子爬虫--捧腹网
- 企业生产发展从第一次工业革命到信息化时代
- 发票识别+发票查验API、发票管理效率
- vsCode 快捷键PDF
- 谷歌浏览器单独下载插件文件crx到本地的方法步骤
- oracle添加索引指定表空间,Oracle 创建索引表空间语法-oracle