這裏只討論HotSpot虛擬機,這也是目前使用的最多的JVM。Sun JDK7 HotSpot虛擬機的內存模型以下圖所示:spring
在Java虛擬機中,方法區是可供各線程共享的運行時內存區域。在不一樣的JDK版本中,方法區中存儲的數據是不同的。併發
在JDK1.6及以前,運行時常量池是方法區的一個部分,同時方法區裏面存儲了類的元數據信息、靜態變量、即時編譯器編譯後的代碼(好比spring 使用IOC或者AOP建立bean時,或者使用cglib,反射的形式動態生成class信息等)等。性能
在JDK1.7及之後,JVM已經將運行時常量池從方法區中移了出來,在JVM堆開闢了一塊區域存放常量池。優化
在Java虛擬機規範中,方法區在虛擬機啓動的時候建立,雖然方法區是堆的邏輯組成部分,可是簡單的虛擬機實現能夠選擇不在方法區實現垃圾回收與壓縮。這個版本的虛擬機規範也不限定實現方法區的內存位置和編譯代碼的管理策略。因此不一樣的JVM廠商,針對本身的JVM可能有不一樣的方法區實現方式。spa
在HotSpot中,設計者將方法區歸入GC分代收集。HotSpot虛擬機堆內存被分爲新生代和老年代,對堆內存進行分代管理,因此HotSpot虛擬機使用者更願意將方法區稱爲老年代。線程
方法區和永久代的關係很像Java中接口和類的關係,類實現了接口,而永久代就是HotSpot虛擬機對虛擬機規範中方法區的一種實現方式。設計
咱們知道在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。blog
上面說過,HotSpot虛擬機在1.8以後已經取消了永久代,改成元空間,類的元信息被存儲在元空間中。元空間沒有使用堆內存,而是與堆不相連的本地內存區域。因此,理論上系統可使用的內存有多大,元空間就有多大,因此不會出現永久代存在時的內存溢出問題。這項改造也是有必要的,永久代的調優是很困難的,雖然能夠設置永久代的大小,可是很難肯定一個合適的大小,由於其中的影響因素不少,好比類數量的多少、常量數量的多少等。永久代中的元數據的位置也會隨着一次full GC發生移動,比較消耗虛擬機性能。同時,HotSpot虛擬機的每種類型的垃圾回收器都須要特殊處理永久代中的元數據。將元數據從永久代剝離出來,不只實現了對元空間的無縫管理,還能夠簡化Full GC以及對之後的併發隔離類元數據等方面進行優化。接口