|--方法區【線程共享】
被全部線共享。
存儲被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼。
在Java虛擬機規範把此區描述爲堆的一個邏輯部分,可是有一個別名Non-Heap,與堆區分開來。
在不少虛擬機來看(HotSpot)把方法區稱爲「永久代」,實際不等價。由於HotSpot虛擬機把GC分代收集擴展至方法區,或者使用永久代來實現方法區。其它如BEA JRockit、IBM JRockit、IBM J9是不存在永久代的。
HotSpot 能夠像管理Java堆同樣管理此部份內存,但這樣有限制-XX:MaxPermSize的限制 。
此部分的垃圾回收針對:
常量池
類型卸載
回收的效果不盡人意,可能出現好多問題。
當方法區沒法知足內存分配時,報OutOfMemeryError
|--運行時常量池
方法區的一部分,用於存放編譯期生成的各類字面量和符號引用。這部份內容在類加載後進入方法區的運行時常量池。
Java虛擬機規範沒有細節要求,可自由實現。
具備動態性,除了在編譯時期產生的常量外,還能夠在運行時產生 ,使用的比較多的是String 的intern()方法。
受到方法區內存的限制 。
異常:
OutOfMemeryError。
|--堆【線程共享】
大多數狀況下,是Java虛擬機管理的內存中的最大的一塊。
被全部的線程共享。
存放對象實例。
是垃圾收集管理的主要區域。也稱爲「GC堆」。
能夠分爲:
新生代、老生代
Eden空間、From Survivor空間、To Survivor空間。
能夠處於物理上不連續的內存空間中,但邏輯上必須是連續的。
能夠設置成固定的,也能夠是擴展的。大多數是可擴展的。
異常:
若是在堆中沒有內存完成分配,而且堆也沒法擴展時,拋出OutOfMemeryError。
|--虛擬機棧【線程隔離】
線程私有的,生命週期與線程相同。描述的是Java方法執行的內存模型。每一個方法在執行時會建立一個棧楨。
棧楨用於存儲局部變量、操做數棧、動態連接、方法出口等信息。
方法的執行過程至關於棧楨入棧到出棧的過程。
存放了編譯期可知的各類基本數據類型(boolean、byte、char、short、int、float、double、long)和對象類型的引用 。
其中64位長度的long和double佔兩個局部變量空間(Slot),其他的數據類型佔一個。
局部變量所需的內存空間在編譯時分配完成,當進入一個方法時,方法須要在楨中分配多大的局部變量空間是徹底肯定的,方法運行期間不會改變局部變量空間的大小。
異常:
若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError。
若是虛擬機容許擴展,擴展時沒法申請到足夠的內存,將拋出OutOfMemeryError。
|--本地方法棧【線程隔離】
功能與虛擬機棧相同,只不過是爲Native方法服務。
虛擬機規範中沒有對此進行強制規定,能夠自由實現。Sun HotSpot虛擬機則直接把本地方法棧和虛擬機棧合二爲一。
異常:會拋出StackOverflowError和OutOfMemeryError。
|--程序計數器【線程隔離】
若是線程執行的是Java方法,計數器記錄正在執行的虛擬機字節碼指令地址;
若是執行的是Native方法,計數器爲空。
內存中惟一一個在Java虛擬機規範中沒有規定OutOfMemaryError的區域。
|--直接內存
不是運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域。但被頻繁使用,可能致使OutOfMemeryError。
NIO,可使用Native函數庫直接分配堆外內存,而後經過一個存在Java堆中的DirectByteBuffer對象做爲這塊內存的引用進行操做。這樣能夠避免在Java堆和Native堆中來回複製數據。
不受Java堆大小的限制,可是會受系統內存的限制。配置-Xmx時有時會忽略此部份內存,形成動態擴展時出現OutOfMemeryError。函數