天天看點

JVM系列-05-方法區-永久帶VS元空間1 JVM(HotSpot)記憶體模型2 官方對方法區的介紹3 常說的永久帶和方法區是什麼關系?4 jdk8中的方法區參考文章

  • JVMHotSpot記憶體模型
  • 官方對方法區的介紹
  • 常說的永久帶和方法區是什麼關系
  • jdk8中的方法區
  • 參考文章

1 JVM(HotSpot)記憶體模型

JVM系列-05-方法區-永久帶VS元空間1 JVM(HotSpot)記憶體模型2 官方對方法區的介紹3 常說的永久帶和方法區是什麼關系?4 jdk8中的方法區參考文章

上面這種圖是HotSpot虛拟機的記憶體模型,本篇文章主要介紹方法區。

因為方法區在JDK1.7及其以前版本中的實作方式——

永久帶

在JKD8中被移除了。

至于其他部分不太了解的可以閱讀這篇文章:http://blog.csdn.net/hylexus/article/details/53564865

2 官方對方法區的介紹

以下是《Java虛拟機規範(JavaSE7)》一書中對方法區的描述:

在 Java 虛拟機中,方法區( Method Area) 是可供各條

線程共享

運作時記憶體區域

。方法區與傳統語言中的編譯代碼儲存區( Storage Area Of Compiled Code)或者作業系統程序的正文段( Text egment)的作用非常類似,它

存儲了每一個類的結構資訊

,例如運作時常量池( Runtime Constant Pool)、字段和方法資料、構造函數和普通方法的位元組碼内容、還包括一些在類、執行個體、接口初始化時用到的特殊方法( §2.9)。

方法區在虛拟機啟動的時候被建立,雖然

方法區是堆的邏輯組成部分

,但是簡單的虛拟機實作可以選擇在這個區域不實作垃圾收集。這個版本的 Java 虛拟機規範也不限定實作方法區的記憶體位置和編譯代碼的管理政策。方法區的容量可以是固定大小的,也可以随着程式執行的需求動态擴充,并在不需要過多空間時自動收縮。方法區在實際記憶體空間中可以是不連續的。

Java 虛拟機實作應當提供給程式員或者最終使用者調節方法區初始容量的手段,對于可以動态擴充和收縮方法區來說,則應當提供調節其最大、最小容量的手段

如果方法區的記憶體空間不能滿足記憶體配置設定請求,那 Java 虛拟機将抛出一個

OutOfMemoryError

異常。

總之,就是用來存儲類的描述資訊——中繼資料的。它有一個别名叫做Non-Heap(非堆)。

3 常說的永久帶和方法區是什麼關系?

平時,說到永久帶(

PermGen space

)的時候往往将其和方法區不加差別。這麼了解在一定角度也說的過去。

因為,《Java虛拟機規範》隻是規定了有方法區這麼個概念和它的作用,并沒有規定如何去實作它。那麼,在不同的 JVM 上方法區的實作肯定是不同的了。

同時,大多數用的JVM都是Sun公司的HotSpot。在HotSpot上把GC分代收集擴充至方法區,或者說使用永久代來實作方法區。

雖然可以牽強的解釋這種将方法區和永久帶等同對待觀點。但最終方法區和永久帶還是不同的。一個是标準一個是實作。這就相當于你将java中的接口和接口的實作等同對待了一樣。

同時,這種牽強的解釋也僅僅是在HotSpot虛拟機上才能勉強成立。其他的虛拟機實作并沒有永久帶這一說法。

有人說,HotSpot之是以用永久帶來實作方法區是因為這樣可以不必專門為方法區編寫一套記憶體管理的代碼。

大小調節

在1.7之前,可以使用如下參數來調節方法區的大小

  • -XX:PermSize
    • 方法區初始大小
  • -XX:MaxPermSize
    • 方法區最大大小
    • 超過這個值将會抛出

      OutOfMemoryError

      異常:java.lang.OutOfMemoryError: PermGen

4 jdk8中的方法區

在jdk8中已經将永久帶移除了。也就是說

-XX:PermSize

這些參數在jdk8中将是無效的。

移除了,肯定有人來代替他。就是新出現的元空間(Metaspace)來代替原來的永久帶。

上文也提到了,方法區中主要存放的是一些描述性資訊,即中繼資料。元空間這個名字起得還是挺形象的,至少比原來的永久帶要更加見名之意了。

《Java虛拟機規範(JavaSE7)》中也說了

方法區是堆的邏輯組成部分

實際上JDK1.7中,存儲在永久代的部分資料就已經轉移到了

Java Heap

或者是

Native Heap

。但永久代仍存在于JDK1.7中,但是并沒完全移除。

大小調節

在1.8中,可以使用如下參數來調節方法區的大小

  • -XX:MetaspaceSize
    • 元空間初始大小
  • -XX:MaxMetaspaceSize
    • 元空間最大大小
    • 超過這個值将會抛出

      OutOfMemoryError

      異常:java.lang.OutOfMemoryError: Metadata space
    • 在jdk1.7中抛出的異常是這樣:java.lang.OutOfMemoryError: PermGen

參考文章

  • 《深入了解JVM》
  • 《Java虛拟機規範(JavaSE7)》
  • 《Java虛拟機規範(JavaSE8)》