2016-08-03 27 views
1

我正在運行Oracle提供的64位Java 1.8 Hotspot JVM。我一直試圖圍繞JVM行爲的差異來解決當使用不同GC機制時壓縮對象指針的問題。例如:G1和CMS的UseCompressedOops kick-in閾值不同

$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32766m -Xmx32766m 

bool UseCompressedClassPointers  := true  {lp64_product} 
bool UseCompressedOops     := true  {lp64_product} 

$ java -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -Xms32767m -Xmx32767m 

bool UseCompressedClassPointers  = false  {lp64_product} 
bool UseCompressedOops     = false  {lp64_product} 

$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32736m -Xmx32736m 

bool UseCompressedClassPointers  := true  {lp64_product} 
bool UseCompressedOops     := true  {lp64_product} 

$ java -XX:+UseG1GC -XX:+PrintFlagsFinal -Xms32737m -Xmx32737m 

bool UseCompressedClassPointers  = false  {lp64_product} 
bool UseCompressedOops     = false  {lp64_product} 

我試圖改變一些其他G1GC旋鈕,但不能得到壓縮的指針優化踢在堆規模以上32736 MB爲G1。但是,您可以清楚地看到,CMS可以使用壓縮指針來存儲最大32766 MB的堆大小。我想了解什麼控制不同的GC算法的這個閾值。

+0

最後一個命令「-XX:+ G1GC」中的G1標誌是否爲錯字? – IceMan

+0

@IceMan是的,謝謝你指出。我只是糾正它。 –

回答

0

,但不能把它壓縮的指針優化,因爲對象對齊默認情況下8字節的邊界,這意味着最低的3位是多餘的,是踢在堆規模以上32736 MB

這是正常的通過移位消除,這意味着32位對象指針最多可以處理具有該對齊的4GB * 8價值的對象。

如果你想在壓縮的oops中使用多於32GB的數據,你需要通過-XX:ObjectAlignmentInBytes=16將對象對齊增加到16個字節。請注意,這會使較小的對象變大,即浪費一些內存,所以您將不得不測量它是否實際獲得任何東西。

This answer有一些額外的診斷選項可能是有趣的。

+0

就是這樣。我沒有使用超過32GB的堆。 32766 MB和32736 MB都小於32 GB。 CMS使用壓縮指針直到32766 MB,但G1只使用到32736 MB堆。我無法理解這些閾值之間的區別。 (編輯問題以清楚地反映我所遇到的困惑。) –

+0

爲什麼這種微小的差異甚至是重要的?無論如何,我鏈接的答案包含診斷標誌,它們可能有助於您的「問題」。 – the8472