一,程序計數器服務器
程序計數器(Program Counter Register)是一塊較小的內存區域,它能夠看做是當前線程所執行的字節碼指示器。每條線程都須要由一個獨立的的程序計數器,各條線程之間計數器互不影響,獨立存儲,咱們稱這類內存區域爲「線程私有」的內存。若是線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若是正在執行的是Native方法,這個計數器值則爲空(Undefined)。此內存區域是惟一一個在Java虛擬機規範中沒有規定任何OutOfMemoryError狀況的區域。函數
二,Java虛擬機棧性能
與程序計數器同樣,Java虛擬機棧(Java Virtual Machine Stacks)也是線程私有的,它生命週期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每一個方法在執行的同時都會建立一個棧幀(Stack Frame)用於存儲局部變量表、操做數棧、動態連接、方法出口等。操作系統
若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError異常;若是虛擬機棧能夠動態擴展(當前大部分的Java虛擬機均可動態擴展,只不過 Java虛擬機規範中也容許固定長度的虛擬機棧),若是擴展時沒法申請到足夠的內存,就會拋出OutOfMemoryError異常。線程
三,本地方法棧設計
本地方法棧(Native Method Stack)與虛擬機棧所發揮的做用是很是類似的,它們之間的區別不過是虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則爲虛擬機使用到的 Native方法服務。與虛擬機棧同樣,本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError顯常。對象
四,Java堆blog
對於大多數應用來講,Java堆(Java Heap)是Java虛擬機所管理的內存空最大的一塊,Java堆是被全部線程共享的一塊內存區域,在虛擬機啓動時建立。此內存區域的惟一目的賴是在放過象實例。接口
Java堆是垃圾收集器管理的主要區域,所以不少時候也被稱作「GC堆」。若是在堆中沒有內存完成實例分配,而且堆也沒法在擴展時,會拋出OutOfMemoryError異常。生命週期
五,方法區
方法區(Method Area)與Java堆同樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。對於習慣在HotSpot虛擬機上開發、部署程序的開發者來講,不少人都跟願意把方法區成爲「永久代」(Permanent Generation),本質上二者並不等價,僅僅是由於Hotspot虛擬機的設計團隊選擇把Gc分代收集擴展至方法區,或者說使用永久代來實現方法區而已,這樣HotSpot的垃圾收集器能夠像管理Java堆同樣管理這部份內存,可以省去專門爲方法區編寫。
當方法區沒法知足內存分配需求時,將拋出OutOfMemoryError。
六,運行時常量池
運行時常量池(Runtime Constant Pool)是方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用於存放編譯期生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池中存放。
當常量池沒法再申請到內存時會拋出OutOfMemoryErrorr異常。
七,直接內存
直接內存(Direct Memory)並非虛擬機運行時數據區的一部分,也不是Java 虛擬機規範中定義的內存區域。一可是這部份內存也被頻繁地使用,並且也可能致使OutOfMemoryErrorr異常出現,因此放到這裏一塊兒講解。
在JDK 1.4中新加人了NIO(New lnput/Output)類,引人了一種基於通道(Channel) 緩衝區(Bufler)的I/O方式,它可使用Native函數庫直接分配堆外內存,而後經過一個存儲在Java堆中的DirectByteBuffer對象做爲這塊內存的引用進行操做。這樣能在一些場中顯著提升性能,由於避免了在Java堆和Native堆中來回複製數據。
顯然,本機直接內存的分配不會受到Java堆大小的限制,可是,既然是內存,確定仍是受到本機總內存(包括RAM以及SWAP區或者分頁文件)大小以及處理器尋址空間的限制。服務器管理員在配置虛擬機參數時,會根據實際內存設置-Xmx等參數信息,但常常忽直接內存,使得各個內存區域總和大於物理內存限制(包括物理的和操做系統級的限制),而致使動態擴展時出現OutOfMemoryErrorr異常。