Java虛擬機在運行Java程序時,會將它所管理的內存劃分爲若干個內存區域。這些數據區域有各自的用途、以及建立和銷燬時間。有的隨着虛擬機啓動而啓動,有的區域則依賴java線程的啓動和結束來創建和銷燬。
Java虛擬機運行時數據區圖以下(來自深刻理解Java虛擬機:jvm的高級特性和實踐):
如下對運行時數據區的各個區域作相應的解釋:java
程序計數器是一個較小的內存空間,能夠把它看作當前線程執行的字節碼時的行號指示器。字節碼解釋器的工做就是經過不斷改變這個計數器來選擇下一條須要執行的字節碼指令、分支、循環等功能。
因爲java的多線程是經過輪流切換線程分配處理器執行時間的方式來實現的,因此,在任何一個時間點,一個處理器只會執行一條線程中的指令。所以,爲了能保證線程切換後能恢復到正確的位置,每條線程都須要有一個獨立的程序計數器。各條線程計數器之間互不影響,獨立存儲。咱們稱這類內存區域爲「線程私有」的內存。
若是線程正在執行的是一個java方法,計數器記錄的是虛擬機正在執行的字節碼指令地址。
若是線程正在執行的是一個Native方法,這個計數器值則爲空。
此內存區域是惟一一個在java虛擬機規範中沒有規定任何OutOfMemoryError的狀況的區域
總結:算法
與程序計數器同樣,虛擬機棧也是線程私有的,它的生命週期和線程相同。虛擬機棧描述的是java方法執行的內存模型:每一個java方法在執行時都會建立一個棧幀(stack frame)用於存儲局部變量表、操做數棧、動態連接、方法出口等信息。每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧出棧的過程。
總結:數據結構
本地方法棧和虛擬機棧所發揮的做用是很是類似的,只不過虛擬機棧是爲java虛擬機執行java方法(字節碼)而服務,而本地方法棧則是爲了虛擬機中使用到的Native方法服務。
在虛擬機規範中沒有明確規定本地方法棧使用的語言、數據結構沒有強制約定。具體的虛擬機能夠自由實現它。
總結:多線程
對於大多數應用來講,Java堆(Heap)是java虛擬機管理的最大一塊內存區域,java堆是全部線程共享的一塊內存區域,會在虛擬機啓動時建立。
Java堆內存的惟一目的就是:存放對象實例
因爲如今收集器都採用分代收集算法,因此java堆還能夠分爲新生代和老年代。
總結:jvm
方法區和Java堆同樣,是被全部線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等。
該區域的內存回收目標主要是針對常量池的回收和對類型的卸載
總結:spa
運行時常量池是方法區的一部分,Class文件除了有類的版本、字段、方法、接口等描述信息外。還有一項重要信息就是常量池,用於存儲編譯器生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池中。
總結:線程
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">對象