這裏主要以HotSpot虛擬機做爲描述對象java
程序計數器是一塊較小的內存空間,是當期線程執行字節碼的行號指示器。
字節碼經過改變這個計數器的值來肯定下一個須要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都須要依賴計數器來完成。算法
java虛擬機的多線程是經過線程的輪流切換並分配處理器執行時間的方式來實現的,在任何一個肯定的時刻一個處理器都只會執行一條線程的指令。爲了線程切換後恢復到正確的執行位置,每條線程都須要有一個獨立的程序計數器。因此這塊內存是「線程私有」的內存。數組
該區域是虛擬機規範中爲一個沒有規定任何OutOfMemoryError狀況的區域。多線程
Java虛擬機棧是線程私有的。spa
生命週期與線程相同。線程
描述的是java方法執行的內存模型:每個方法執行的同時都會建立一個棧幀(Starck Frame)用於存儲局部變量表、操做數棧、動態連接等信息。每一個方法的開始調用到執行完成的過程都對應着一個棧幀在虛擬機棧中入棧到出棧的過程指針
局部變量表中存放了編譯期可知的各類基本數據類型(boolean、byte、char、short、int、float、long、double)以及對象引用(reference類型,它不是對象自己,多是一個指向:對象起始地址的引用指針、對象句柄)和returnAddress類型(指向一條字節碼指令的地址)。對象
虛擬機規範中對這塊區域規定了兩種異常情況:
1> 若是線程請求的棧深度大於虛擬機所容許的深度將拋出StackOverflowError異常
2> 若是虛擬機棧能夠動態擴展,而擴展時沒法申請到足夠的內存,就會拋出OutOfMemoryError異常blog
與虛擬機棧的做用很是相識,區別就是:虛擬機棧爲虛擬機執行java方法服務,而本地方法棧爲虛擬機使用到的native方法服務。SunHotSpot虛擬機把虛擬機棧和本地方法棧合併了。生命週期
與虛擬機棧同樣本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常
因此本地方法棧也是線程私有的
從內存回收的角度來看因爲如今的垃圾收集器都是採用分代收集的算法,因此這塊區域又可細分爲新生代和老年代,默認狀況新生代又可分爲一個Eden空間和兩個Survivor空間。從內存分配的角度來看,線程共享的java heap可能須要劃分出多個線程私有的分配緩衝區(Thread Local Allocation Buffer, TLAB)
java堆是虛擬機所管理的內存中最大的一塊區域,也是垃圾收集器管理的主要區域。
虛擬機啓動時建立,全部線程共享。
惟一目的就是用來存放對象實例。全部的對象實例以及數組都要在堆上分配內存
能夠經過-Xmx和-Xms來控制heap的可擴展性。
若是heap中沒有足夠的內存完成實例的分配,而且也沒法再擴展時將會拋出OutOfMemoryError異常
對於HotSpot虛擬機上開發者也把這塊區域成爲「永久代」(Permanent Generation)。二者本質上並不等價,只是爲了垃圾收集器能夠像管理 Java 堆同樣去管理這部分區域而把GC分代收集擴展到了這裏。
線程共享的區域。
用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯(Just In Time,JIT編譯器)後的代碼等數據。
能夠經過-XX:PermSize 和 -XX:MaxPermSize來設置這塊區域的可擴展性
可能會拋出OutOfMemoryErrory
這塊區域是方法區的一部分。用於存放編譯期生成的各類字面量和符號引用,這部份內容再類加載後存入方法區的運行時常量池中。既然是方法區的一部分,天然受到方法區內存的限制,當常量池沒法申請到內存時會拋出OutOfMemoryErrory