**目前有三大Java虛擬機:HotSpot,oracle JRockit,IBM J9。**
>[info] JRockit是oracle發明的,用于其WebLogic服務器,IBM JVM是IBM發明的用于其Websphere服務器(所以在某行開發的時候,他們用的是IBM的JDK,因為他們使用的IBM的應用程序服務器Websphere,使用其他JDK可能存在兼容性問題)。
>[success] JRockit和J9不存在永久代這種說法。這里只討論HotSpot虛擬機,這也是目前使用的最多的JVM。Sun JDK7 HotSpot虛擬機的內存模型如下圖所示:

### 1、什么是方法區
>[info] 在Java虛擬機中,方法區是可供各線程共享的運行時內存區域。
> 在不同的JDK版本中,方法區中存儲的數據是不一樣的。
> 在JDK1.6及之前,運行時常量池是方法區的一個部分,同時方法區里面存儲了類的元數據信息、靜態變量、即時編譯器編譯后的代碼(比如spring 使用IOC或者AOP創建bean時,或者使用cglib,反射的形式動態生成class信息等)等。
> 在JDK1.7及以后,JVM已經將運行時常量池從方法區中移了出來,在JVM堆開辟了一塊區域存放常量池。
### 2、方法區和永久代的關系
>[info] 在Java虛擬機規范中,方法區在虛擬機啟動的時候創建,雖然方法區是堆的邏輯組成部分,但是簡單的虛擬機實現可以選擇不在方法區實現垃圾回收與壓縮。這個版本的虛擬機規范也不限定實現方法區的內存位置和編譯代碼的管理策略。所以不同的JVM廠商,針對自己的JVM可能有不同的方法區實現方式。
>[success] 在HotSpot中,設計者將方法區納入GC分代收集。HotSpot虛擬機堆內存被分為新生代和老年代,對堆內存進行分代管理,所以HotSpot虛擬機使用者更愿意將方法區稱為老年代。
> 方法區和永久代的關系很像Java中接口和類的關系,類實現了接口,而永久代就是HotSpot虛擬機對虛擬機規范中方法區的一種實現方式。
>[warning] 我們知道在HotSpot虛擬機中存在三種垃圾回收現象,minor GC、major GC和full GC。對新生代進行垃圾回收叫做minor GC,對老年代進行垃圾回收叫做major GC,同時對新生代、老年代和永久代進行垃圾回收叫做full GC。許多major GC是由minor GC觸發的,所以很難將這兩種垃圾回收區分開。major GC和full GC通常是等價的,收集整個GC堆。但因為HotSpot VM發展了這么多年,外界對各種名詞的解讀已經完全混亂了,當有人說“major GC”的時候一定要問清楚他想要指的是上面的full GC還是major GC。
### 3、元空間
>[danger] 上面說過,HotSpot虛擬機在1.8之后已經取消了永久代,改為元空間,類的元信息被存儲在元空間中。元空間沒有使用堆內存,而是與堆不相連的本地內存區域。所以,理論上系統可以使用的內存有多大,元空間就有多大,所以不會出現永久代存在時的內存溢出問題。這項改造也是有必要的,永久代的調優是很困難的,雖然可以設置永久代的大小,但是很難確定一個合適的大小,因為其中的影響因素很多,比如類數量的多少、常量數量的多少等。永久代中的元數據的位置也會隨著一次full GC發生移動,比較消耗虛擬機性能。同時,HotSpot虛擬機的每種類型的垃圾回收器都需要特殊處理永久代中的元數據。將元數據從永久代剝離出來,不僅實現了對元空間的無縫管理,還可以簡化Full GC以及對以后的并發隔離類元數據等方面進行優化。