不分配大內存給 Elasticsearch,事實上 jvm 在內存 < 32G 的時候會采用一個:內存對象指針壓縮技術。
需要明白:不一定是 32GB,一般 linux 系統上都是介於 (31, 32),所以為了安全起見我們統一都可以設置為 31GB。
在 java 中,所有的對象都分配在堆上,然后有一個指針引用它。指向這些對象的指針大小通常是CPU的字長大小,不是 32bit 就是 64bit,這取決於你的處理器,指針指向了你的值的精確位置。
對於32位系統,內存最大可使用4G。
64系統可以使用更大的內存。但是64位的指針意味着更大的浪費,因為你的指針本身大了。浪費內存不算,更糟糕的是,更大的指針在主內存 和 緩存器之間移動數據的時候,會占用更多的帶寬。
java 使用一個叫內存指針壓縮的技術來解決這個問題。
它的指針不再表示對象在內存中的精確位置,而是表示偏移量。這意味着32位的指針可以引用40億個對象,而不是40億個字節。最終,也就是說堆內存長到32G的物理內存,也可以用 32bit 的指針表示。
一旦你越過那個神奇的 30-32G 的邊界,指針就會切回普通對象的指針,每個對象的指針都變長了,就會使用更多的 CPU、內存、帶寬,也就是說你實際上失去了更多的內存。
事實上當內存到達40-50GB的時候,有效內存才相當於使用內存對象指針壓縮技術時候的32G內存。
結論就是:即便你有足夠的內存,也盡量不要超過32G,因為它浪費了內存,降低了CPU的性能,還要讓GC應對大內存。