java 記憶體移到堆外!!! Jvm gcih 淘寶優化JVM實踐
阿新 • • 發佈:2019-01-08
什麼是GCIH
GC-Invisible Heap,簡稱GCIH,是一種將Java物件從Java堆內移動到堆外,並且可以在JVM間共享這些物件的技術。
為什麼要用GCIH
GCIH顧名思義就是GC訪問不到的堆,它是對JVM記憶體管理機制的一個有益的補充。 在某些特殊的應用中有大量生命週期很長的物件,在應用執行的整個過程中它們都存在,不需要被GC回收。如果這類物件很多,總體佔用記憶體比例高,那麼他們的存在將給GC帶來很多不必要的工作負擔。例如在淘寶的很多應用中都具有大量的Forest物件,目前這些物件已經佔用超過400MB,它們本身在應用提供服務前建立,在服務過程中永遠存在。那麼實際在GC的收集工作中針對這些物件的所有訪問、操作其實都是“無用功”。如果我們把這些物件 從Java堆內移動到堆外,那麼這些物件所佔用的Java堆內空間將被釋放,GC的工作量將會降低,從而每次full GC的時間將會縮短。 除此以外,目前JVM間沒有很高效的記憶體/物件共享技術,GCIH為在JVM間共享記憶體/物件提供了必要的基礎。通過這種技術可以將那些移動到GCIH內物件在JVM間共享,從而減少記憶體的總體佔用。
GCIH + Hesper + Forest線上測試結果對比
下面的效能測試資料來自於線上gcih + hesper + forest的實際壓測資料,具體結論由淘寶效能測試團隊統計。
- 系統load對比
在相同的tps下,採用gcih的hesper響應時間明顯要比不採用gcih的hesper的響應時間要低。隨著壓力的不斷增加,tps超過55後,非gcih的hesper響應時間明顯上升速度加快,當tps上升至72後,響應時間直接飆至200ms以上。而採用gcih的響應時間上升速度則相對於平緩。
- 機器資源消耗對比
在tps處於20~50之間時,gcih的load要略低於非gcih。在tps超過55後,非gcih的load出現急速上升。 在tps相同的情況下,gcih的cpu消耗約降低20%~30%.
- 單機最大能力對比
當load達到5~6之間、且RT<200ms的情況下,hesper(非gcih)的tps約為46~55左右,hesper(gcih)的tps值約為60~68左右。此時,hesper(非gcih)的單機能力比hesper(gcih)提升20%; 當load<15,cpu使用率<85%的情況下,hesper(非gcih)的最大單機能力為tps:68~70,hesper(gcih)的tps值約為88左右。此時計算,採用gcih的hesper應用單機最大能力可提升25%。
- 綜上:gcih的效能明顯優於非gcih,可以使單機能力提升20%左右。
GCIH記憶體共享
有關GCIH記憶體共享
GCIH 記憶體共享有以下特點:
- 不經過JNI呼叫
- 沒有序列化和反序列化
- GC效能提高
- 資料更集中,cache命中率提高
GCIH記憶體共享與Hadoop
- Map/Reduce 有時需要一些公用的物件,每個client JVM都有一份拷貝。
- 一旦初始化好,在使用過程中是隻讀的
- 物件比較大,佔用較多記憶體,甚至成為瓶頸
- 一個實際場景,dump中心的UDP,用來做join的一些公共Hashmap共享後可以節約記憶體,甚至可能提高效率(如果記憶體是瓶頸)
下圖顯示了使用GCIH記憶體共享功能後的Hadoop系統狀況,左邊的圖表示使用GCIH前系統內每個JVM程序內均有一份物件的拷貝, 右邊的圖顯示使用GCIH後多個JVM程序共享一份資料,有效降低了實體記憶體的使用。