Don’t Cross 32 GB!

看elasticsearch官方文檔時(shí)赔蒲,提到的一個(gè)觀點(diǎn):Don’t Cross 32 GB。是因?yàn)楫?dāng)JVM堆少于32G時(shí)良漱,HotSpot虛擬機(jī)會(huì)啟用一個(gè)壓縮對(duì)象指針舞虱。而如果超過32G,這個(gè)壓縮對(duì)象指針就會(huì)失效母市。那么矾兜,究竟這個(gè)臨界值的精確值是多大呢?開啟壓縮指針相比沒有開啟窒篱,能節(jié)省多少內(nèi)存呢焕刮?讓我們一探究竟舶沿!

Don’t Cross 32 GB!

在Java的世界里墙杯,絕大部分對(duì)象分配在堆里,并且被一個(gè)指針引用(Student stu = new Student()括荡,new的這個(gè)Student對(duì)象就是分配在堆里高镐,stu就是持有這個(gè)對(duì)象的應(yīng)用)。

32位的操作系統(tǒng)畸冲,最大只支持4G內(nèi)存(即2^32)嫉髓。當(dāng)然,對(duì)于當(dāng)下來說邑闲,32位服務(wù)器應(yīng)該是絕種了算行,所以本文討論的是64位操作系統(tǒng)。對(duì)于64位操作系統(tǒng)來說苫耸,理論上分配的堆可以非常非常大州邢。但是,64位指針的開銷就意味著有更多的浪費(fèi)空間褪子,這僅僅是因?yàn)橹羔樃罅刻省1壤速M(fèi)空間更糟糕的是骗村,64位指針在主內(nèi)存和多級(jí)緩存之間移動(dòng)數(shù)據(jù)的時(shí)候,還會(huì)消費(fèi)更多的帶寬呀枢。

Java用"compressed oops"術(shù)解決了這個(gè)問題胚股,指針不再是指向內(nèi)存中精確位置,而是對(duì)象的偏移量(原文: Instead of pointing at exact byte locations in memory, the pointers reference object offsets)裙秋。這就意味著琅拌,32位指針能引用2^32 個(gè)對(duì)象(大約43億個(gè)對(duì)象),而不是引用總計(jì)2^32 個(gè)字節(jié)大小對(duì)象残吩。所以财忽,堆大小直到32G左右還能保持32位指針。

一旦你越過這個(gè)32G--一個(gè)具有魔法般的數(shù)值泣侮。指針將切回到普通的對(duì)象指針即彪。每個(gè)指針變大,意味著需要更多的CPU活尊,內(nèi)存和帶寬隶校,真正用來保持對(duì)象的內(nèi)存就會(huì)更少。這就可能導(dǎo)致一種奇怪的現(xiàn)象蛹锰,使用compressed oops的32G的堆和40~50G沒有使用compressed oops的堆保存的對(duì)象數(shù)量是一樣的深胳。

這個(gè)事實(shí)告訴我們:即使你有多余的內(nèi)存,也應(yīng)該盡量避免超過32G這個(gè)界限铜犬。它會(huì)浪費(fèi)內(nèi)存舞终,降低CPU性能,并且大堆情況下GC表現(xiàn)也一般般癣猾。更麻煩的是敛劝,那么大的堆,DUMP分析將是一件極其痛苦纷宇,極其麻煩的事情夸盟。相信我,你一定不想碰到那種局面像捶。

應(yīng)該設(shè)置多大上陕?

32G是個(gè)近似值,這個(gè)臨界值跟JVM和平臺(tái)有關(guān)拓春。如果不想精確設(shè)置的話释簿,31G是個(gè)決定安全的數(shù)值,31G肯定默認(rèn)開啟compressed oops硼莽。我們可以通過增加JVM參數(shù)-XX:+PrintFlagsFinal庶溶,驗(yàn)證UseCompressedOops的值,從而得知,到底是不是真的開啟了壓縮指針渐尿,還是壓縮指針失效醉途!

實(shí)踐才是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)!JUST DO IT砖茸!讓我們動(dòng)手驗(yàn)證這個(gè)臨界值吧隘擎!

驗(yàn)證情況--JDK8前提下,32760m的堆是開啟壓縮指針的凉夯,32770m的堆壓縮指針已經(jīng)關(guān)閉:

[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內(nèi)存

JVM大堆的缺點(diǎn)太多了震桶;

  • 超過32G壓縮指針失效;
  • DUMP分析將是災(zāi)難征绎;
  • 堆越大蹲姐,GC表現(xiàn)越差;

總之人柿,不要嘗試吃這個(gè)螃蟹柴墩!那如果我是在一家有錢任性的公司,服務(wù)器牛逼的不要不要的凫岖,都是128G起步江咳!畢竟不要讓貧窮限制了想象!

這種情況下哥放,我有小建議:開多個(gè)32G的JVM實(shí)例歼指。4個(gè)32G的JVM實(shí)例絕對(duì)比1個(gè)128G實(shí)例表現(xiàn)要好。

簡(jiǎn)單測(cè)試驗(yàn)證

筆者做了一個(gè)簡(jiǎn)單測(cè)試甥雕,驗(yàn)證一下這個(gè)問題:分配設(shè)置Xmx為Xmx32760mXmx32770m踩身,Xmn都是100M(S0:S1:Eden默認(rèn)1:1:8)∠總計(jì)分配一個(gè)包含8個(gè)對(duì)象類型和8個(gè)原子類型以及String惰赋,總計(jì)17個(gè)類型屬性的對(duì)象1kw次宰掉『巧冢看它們分別觸發(fā)了多少YGC,結(jié)論如下表所示:

實(shí)驗(yàn)次數(shù) 開啟壓縮指針YGC次數(shù) 關(guān)閉壓縮指針YGC次數(shù)
1 17.53 21.91
2 17.54 21.92
3 17.52 21.94

由執(zhí)行結(jié)果可知轨奄,Young區(qū)完全一樣的情況下孟害,開啟壓縮指針相比關(guān)閉壓縮指針,能節(jié)省20%多的內(nèi)存挪拟。由此可知挨务,32G還真是一個(gè)奇妙的魔法數(shù)值!另外需要說明的是YGC次數(shù)有小數(shù),是表示Eden區(qū)占用比例谎柄,比如17.52次YGC表示發(fā)生了17次YGC并且Eden還占了52%丁侄。

執(zhí)行的命令:

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

說明:-Xmx32760m -Xms32760m即表示開啟壓縮指針;-Xmx32770m -Xms32770m即表示關(guān)閉壓縮指針朝巫。

  • 附:測(cè)試源碼
/**
 * @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;

    // 省略帶參數(shù)構(gòu)造方法
}
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);
            }
        }
        // 留點(diǎn)時(shí)間采集GC信息
        Thread.sleep(20000);
    }
}

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鸿摇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子劈猿,更是在濱河造成了極大的恐慌拙吉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揪荣,死亡現(xiàn)場(chǎng)離奇詭異筷黔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)仗颈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門佛舱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挨决,你說我怎么就攤上這事名眉。” “怎么了凰棉?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵损拢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我撒犀,道長(zhǎng)福压,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任或舞,我火速辦了婚禮荆姆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘映凳。我一直安慰自己胆筒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布诈豌。 她就那樣靜靜地躺著仆救,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矫渔。 梳的紋絲不亂的頭發(fā)上彤蔽,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音庙洼,去河邊找鬼顿痪。 笑死镊辕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚁袭。 我是一名探鬼主播征懈,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼揩悄!你這毒婦竟也來了受裹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤虏束,失蹤者是張志新(化名)和其女友劉穎棉饶,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镇匀,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡照藻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汗侵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幸缕。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖晰韵,靈堂內(nèi)的尸體忽然破棺而出发乔,到底是詐尸還是另有隱情,我是刑警寧澤雪猪,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布栏尚,位于F島的核電站,受9級(jí)特大地震影響只恨,放射性物質(zhì)發(fā)生泄漏译仗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一官觅、第九天 我趴在偏房一處隱蔽的房頂上張望纵菌。 院中可真熱鬧,春花似錦休涤、人聲如沸咱圆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽序苏。三九已至,卻和暖如春疑故,著一層夾襖步出監(jiān)牢的瞬間杠览,已是汗流浹背弯菊。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工纵势, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踱阿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓钦铁,卻偏偏與公主長(zhǎng)得像软舌,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牛曹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354