标签:false worker 打印 问题 hotspot size pre 表示 nbsp
当JVM堆少于32G时,HotSpot JVM会启用一个压缩对象指针。而如果超过32G,这个压缩对象指针就会失效
在java中,绝大部分对象都分配在堆里,然后通过一个指针(ordinary object pointers (OOP))来引用它。而指针的大小
通常为32位或者64位,取决于你的操作系统
对于32位的系统来说,最大的堆大小也就是4GB(2^32),而对于64位的系统,堆的大小则相对要大很多。但是64位的指针
带来的内存开销也是一种很大的浪费。此外64位指针在主内存和多级缓存之间移动数据的时候,还会消费更多的带宽。
Java使用"compressed oops"方式来避免这种问题,指针不再指向内存中精确字节位置,而是对象的偏移量。
这就意味着,32位指针能引用2^32 个对象(大约43亿个对象),而不是引用总计2^32 个字节大小对象。
所以,堆大小直到32G左右还能保持32位指针。
但是一旦越过32G。指针将切回到普通的对象指针(ordinary object pointers)。
每个指针变大,意味着需要更多的CPU,内存和带宽,真正用来保持对象的内存就会更少。
在这种情况下,分配个40~50G没有使用compressed oops的堆能保存的对象跟使用compressed oops的32G的堆其实是差不多的。
所以:即使你有多余的内存,也要尽量避免超过32gb的堆边界。它会浪费内存,降低CPU性能,并且大堆带来的GC问题也是相对严重很多。
上文说的32G是个近似值,这个临界值跟JVM和平台有关。如果不想那么精确的话,31G是肯定开启compressed oops。
另外我们通过JVM参数-XX:+PrintFlagsFinal来确认JVM究竟有没有开启compressed oops(UseCompressedOops = true表示开启,flase为未开启),
比如:
[etluser@worker01 ~]$ java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) [etluser@worker01 ~]$ java -Xmx32766m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops bool UseCompressedOops := true {lp64_product} [etluser@worker01 ~]$ java -Xmx32767m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops bool UseCompressedOops = false {lp64_product}
可以看到,在堆为32766m的时候,还是使用压缩指针的,但是在32767m的时候,就不使用压缩指针了。
从Elasticsearch v2.2.0开始,在启动日志里elasticsearch会打印出目前堆有没有使用压缩指针,那么在日志里,你看到的大概就是下面这个样子。
[2015-12-16 13:53:33,417][INFO ][env] [Illyana Rasputin] heap size [989.8mb], compressed ordinary object pointers [true]
官网:https://www.elastic.co/guide/en/elasticsearch/guide/current/heap-sizing.html
标签:false worker 打印 问题 hotspot size pre 表示 nbsp
原文地址:https://www.cnblogs.com/zz-ksw/p/12603513.html