JVM |探秘 Metaspace

首先,Metaspace(元空間)是哪一塊區域,官方解釋

In JDK 8, classes metadata is now stored in the

native heap

and this space is called

Metaspace

也就是說,JDK 8 開始把類的元資料放到本地堆記憶體(native heap)中,這一塊區域就叫 Metaspace,中文名叫元空間。

使用本地記憶體有什麼好處呢?最直接的表現就是OOM問題將不復存在,因為預設的類的元資料分配只受本地記憶體大小的限制,也就是說本地記憶體剩餘多少,理論上Metaspace就可以有多大(貌似容量還與作業系統的虛擬記憶體有關?這裡不太清楚),這解決了空間不足的問題。不過,讓 Metaspace 變得無限大顯然是不現實的,因此我們也要限制 Metaspace 的大小:使用

-XX:MaxMetaspaceSize

引數來指定 Metaspace 區域的大小。JVM 預設在執行時根據需要動態地設定

MaxMetaspaceSize

的大小。

GC

如果Metaspace的空間佔用達到了設定的最大值,那麼就會觸發GC來收集死亡物件和類的載入器。根據JDK 8的特性,G1和CMS都會很好地收集Metaspace區(一般都伴隨著Full GC)。

為了減少垃圾回收的頻率及時間,控制吞吐量,對Metaspace進行適當的監控和調優是非常有必要的。如果在Metaspace區發生了頻繁的Full GC,那麼可能表示存在記憶體洩露或Metaspace區的空間太小了。

新增的 JVM 引數

-XX:MetaspaceSize

是分配給類元資料空間(以位元組計)的初始大小(Oracle邏輯儲存上的初始高水位,

the initial high-water-mark

),此值為估計值。MetaspaceSize的值設定的過大會延長垃圾回收時間。垃圾回收過後,引起下一次垃圾回收的類元資料空間的大小可能會變大。

-XX:MaxMetaspaceSize

是分配給類元資料空間的最大值,超過此值就會觸發Full GC,此值預設沒有限制,但應取決於系統記憶體的大小。JVM會動態地改變此值。

-XX:MinMetaspaceFreeRatio

表示一次GC以後,為了避免增加元資料空間的大小,空閒的類元資料的容量的最小比例,不夠就會導致垃圾回收。

-XX:MaxMetaspaceFreeRatio

表示一次GC以後,為了避免增加元資料空間的大小,空閒的類元資料的容量的最大比例,不夠就會導致垃圾回收。