[轉帖]Java 內存分區之什麼是 CCS區 Compressed Class Space 類壓縮空間

瞭解到什麼是ccs區,一般都是實際執行了jstat -gc 之後,看Java堆的gc相關的幾個分區的gc信息,前面的s0,s1,e區,o區,還好猜,研究過分區的,不難猜出來這個分區是啥意思,M區雖然不知道是Metaspace元空間,但是錯把這個M區當成Method area 方法區,也說的過去。這個ccsc就不好說了。之前的看的文章都沒人說這個區是啥。

Java之jstat的用法:Java虛擬機 統計信息查看 工具

不瞭解這幾個簡寫單詞是啥意思的,可以參考一下之前的這個jstat的文章,裏面對每一列的title的簡寫都做了解釋。

什麼是 Compressed Class Space

在 64 位平臺上,HotSpot 使用了兩個壓縮優化技術,Compressed Object Pointers (“CompressedOops”) 和 Compressed Class Pointers。
壓縮指針,指的是在 64 位的機器上,使用 32 位的指針來訪問數據(堆中的對象或 Metaspace 中的元數據)的一種方式。
這樣有很多的好處,比如 32 位的指針佔用更小的內存,可以更好地使用緩存,在有些平臺,還可以使用到更多的寄存器。
當然,在 64 位的機器中,最終還是需要一個 64 位的地址來訪問數據的,所以這個 32 位的值是相對於一個基準地址的值。

下面將描述 Compressed Class Pointers

每個 Java 對象,在它的頭部,有一個引用指向 Metaspace 中的 Klass 結構。

當使用了 compressed class pointers,這個引用是 32 位的值,爲了找到真正的 64 位地址,需要加上一個 base 值:

上面的內容應該很好理解,這項技術對 Klass 的分配帶來的問題是:由於 32 位地址只能訪問到 4G 的空間,所以最大隻允許 4G 的 Klass 地址。這項限制也意味着,JVM 需要向 Metaspace 分配一個連續的地址空間

當從系統申請內存時,通過調用系統接口 malloc(3) 或 mmap(3),操作系統可能返回任意一個地址值,所以在 64位系統中,它並不能保證在 4G 的範圍內。

所以,我們只能用一個 mmap() 來申請一個區域單獨用來存放 Klass 對象。我們需要提前知道這個區域的大小,而且不能超過 4G。顯然,這種方式是不能擴展的,因爲這個地址後面的內存可能是被佔用的。

只有 Klass 結構有這個限制,對於其他的 class metadata 沒有這個必要: 因爲只有 Klass 實例是通過 Java 對象 header 中的壓縮指針訪問的。其他的 metadata 都是通過 64 位的地址進行訪問的,所以它們可以被放到任意的地址上。

所以,我們決定將 Metaspace 分爲兩個區域:non-class part 和 class part。

  • class part:存放 Klass 對象,需要一個連續的不超過 4G 的內存
  • non-class part:包含其他的所有 metadata

class part 被稱作 Compressed Class Space,這個名字會有點怪,因爲 Klass 本身其實沒有使用壓縮技術,而是引用它們的指針被壓縮了。

compressed class space 空間的大小,是通過 -XX:CompressedClassSpaceSize 指定的。

我們需要提前知道自己需要多少內存,它的默認值是 1G。當然這個 1G 並不是真的使用了操作系統的 1G,而是虛擬地址映射。

開關: UseCompressedClassPointers, UseCompressedOops

-XX:+UseCompressedOops 允許對象指針壓縮。

-XX:+UseCompressedClassPointers 允許類指針壓縮。

它們默認都是開啓的,可以手動關閉它們。

如果不允許類指針壓縮,那麼將沒有 compressed class space 這個空間,並且-XX:CompressedClassSpaceSize 這個參數無效。

-XX:-UseCompressedClassPointers 需要搭配 -XX:+UseCompressedOops,但是反過來不是: 我們可以只壓縮對象指針,不壓縮類指針。

這裏面爲什麼這麼規定我也不懂,但是從直覺上來說,壓縮對象指針顯然是比較重要的,能獲得較大的收益。也許就是基於這種考量吧:你連對象指針都不壓縮,類指針壓縮不壓縮又有什麼關係呢?

注意,對象指針壓縮要求堆小於 32G,所以如果堆大於等於 32G,那麼對象指針壓縮和類指針壓縮都會被關閉。

再多的消化不了拉。

參考:

深入理解堆外內存 Metaspace

文章知識點與官方知識檔案匹配,可進一步學習相關知識
Java技能樹首頁概覽143991 人正在系統學習中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章