Java面試題虛擬機器為什麼使用元空間替換了永久代(JVM篇)

码路编程發表於2024-11-03

前言

本來想著給自己放鬆一下,刷刷部落格,突然被幾道面試題難倒!虛擬機器為什麼使用元空間替換了永久代?似乎有點模糊了,那就大概看一下面試題吧。好記性不如爛鍵盤

*** 12萬字的java面試題整理 ***

虛擬機器為什麼使用元空間替換了永久代

「什麼是元空間?什麼是永久代?為什麼用元空間代替永久代?」我們先回顧一下「方法區」吧,看看虛擬機器執行時資料記憶體圖,如下:

方法區和堆一樣,是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯後的程式碼等資料。

「什麼是永久代?它和方法區有什麼關係呢?」
如果在HotSpot虛擬機器上開發、部署,很多程式設計師都把方法區稱作永久代。可以說方法區是規範,永久代是Hotspot針對該規範進行的實現。在Java7及以前的版本,方法區都是永久代實現的。
「什麼是元空間?它和方法區有什麼關係呢?」
對於Java8,HotSpots取消了永久代,取而代之的是元空間(Metaspace)。換句話說,就是方法區還是在的,只是實現變了,從永久代變為元空間了。
「為什麼使用元空間替換了永久代?」

  • 永久代的方法區,和堆使用的實體記憶體是連續的。

「永久代」是透過以下這兩個引數配置大小的~
-XX:PremSize:設定永久代的初始大小
-XX:MaxPermSize: 設定永久代的最大值,預設是64M

對於「永久代」,如果動態生成很多class的話,就很可能出現「java.lang.OutOfMemoryError:
PermGen space錯誤」,因為永久代空間配置有限嘛。最典型的場景是,在web開發比較多jsp頁面的時候。

  • JDK8之後,方法區存在於元空間(Metaspace)。實體記憶體不再與堆連續,而是直接存在於本地記憶體中,理論上機器「記憶體有多大,元空間就有多大」。

可以透過以下的引數來設定元空間的大小:

  • -XX:MetaspaceSize,初始空間大小,達到該值就會觸發垃圾收集進行型別解除安裝,同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放了很少的空間,那麼在不超過MaxMetaspaceSize時,適當提高該值。
  • -XX:MaxMetaspaceSize,最大空間,預設是沒有限制的。
  • -XX:MinMetaspaceFreeRatio,在GC之後,最小的Metaspace剩餘空間容量的百分比,減少為分配空間所導致的垃圾收集
  • -XX:MaxMetaspaceFreeRatio,在GC之後,最大的Metaspace剩餘空間容量的百分比,減少為釋放空間所導致的垃圾收集

「所以,為什麼使用元空間替換永久代?」
表面上看是為了避免OOM異常。因為通常使用PermSize和MaxPermSize設定永久代的大小就決定了永久代的上限,但是不是總能知道應該設定為多大合適, 如果使用預設值很容易遇到OOM錯誤。當使用元空間時,可以載入多少類的後設資料就不再由MaxPermSize控制, 而由系統的實際可用空間來控制啦。

相關文章