JVM(六)---jvm壓縮指針

一 什麼是oop

  OOP = “ordinary object pointer” 普通對象指針。 啓用CompressOops後,會壓縮的對象:

    1. 每個Class的屬性指針(靜態成員變量)

    2. 每個對象的屬性指針

    3. 普通對象數組的每個元素指針

  當然,壓縮也不是萬能的,針對一些特殊類型的指針,JVM是不會優化的。 比如指向 PermGen的Class 對象指針,本地變量,堆棧元素,入參,返回值,NULL指針不會被壓縮

二 爲什麼使用壓縮指針

      在堆中,32位的對象引用(指針)佔4個字節,而64位的對象引用佔8個字節。也就是說,64位的對象引用大小是32位的2倍。64位JVM在支持更大堆的同時,由於對象引用變大卻帶來了性能問題:

增加了GC開銷:64位對象引用需要佔用更多的堆空間,留給其他數據的空間將會減少,從而加快了GC的發生,更頻繁的進行GC。
降低CPU緩存命中率:64位對象引用增大了,CPU能緩存的oop將會更少,從而降低了CPU緩存的效率。
爲了能夠保持32位的性能,oop必須保留32位。那麼,如何用32位oop來引用更大的堆內存呢?答案是——壓縮指針(CompressedOops)。

三 CompressedOops的原理

32位內最多可以表示4GB,64位地址分爲堆的基地址+偏移量,當堆內存<32GB時候,在壓縮過程中,把偏移量/8後保存到32位地址。在解壓再把32位地址放大8倍,所以啓用CompressedOops的條件是堆內存要在4GB*8=32GB以內

所以壓縮指針之所以能改善性能,是因爲它通過對齊(Alignment),還有偏移量(Offset)將64位指針壓縮成32位。換言之,性能提高是因爲使用了更小更節省空間的壓縮指針而不是完整長度的64位指針,CPU緩存使用率得到改善,應用程序也能執行得更快。

四 零基壓縮優化(Zero Based Compressd Oops)

零基壓縮是針對壓解壓動作的進一步優化。 它通過改變正常指針的隨機地址分配特性,強制堆地址從零開始分配(需要OS支持),進一步提高了壓解壓效率。要啓用零基壓縮,你分配給JVM的內存大小必須控制在4G以上,32G以下。如果GC堆大小在4G以下,直接砍掉高32位,

避免了編碼解碼過程 如果GC堆大小在4G以上32G以下,則啓用UseCompressedOop 如果GC堆大小大於32G,壓指失效,使用原來的64位(所以說服務器內存太大不好…)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章