聲明: 本文章說明的是JDK1.7的JVM內存模型
JVM內存模型分爲5個部分,分別爲程序計數器,Java虛擬機棧,本地方法棧,堆,方法區。
一.程序計數器
1.什麼是程序計數器?
程序計數器(Program Counter Register)是一塊較小的內存空間,它可以看作是當前線程所執行的字節碼行號的指示器。
2.程序計數器的作用
1.字節碼解釋器工作通過改變程序計數器的值來選取下一條需要執行的字節碼指令。如:分支、循環、跳轉、異常處理、線程恢復等基礎功能。
2.多線程情況下,程序計數器表示當前線程執行的位置,從而在線程切換的時候知道此線程上一次執行的位置在哪裏。
3.程序計數器的特點
1.一塊較小的內存空間。
2.每個線程獨立的程序計數器,各線程間的程序計數器互不影響,獨立存儲,稱爲“線程私有內存”。
3.生命週期隨着線程的創建而創建,隨着線程的結束而死亡。
4.如果當前線程執行的是Java方法,程序計數器記錄的是當前正在執行的虛擬機字節碼指令的地址。如果當前線程正在執 行的是Native方法,程序計數器的值則爲空(Undefined)。
5.此內存區域是Java虛擬機規範中沒有規定任何的OutOfMemoryError(OOM)情況的區域。
二.Java虛擬機棧
1.什麼是Java虛擬機棧?
Java虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個棧幀(Stack Frame)用來存儲局部變量表(存放了編譯期可知的各種基本數據類型boolean、byte、char、short、int、float、long、double,對象引用reference類型:不等同對象本身,returnAddress類型:指向了一條字節碼指令的地址)、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。
2.Java虛擬機棧的特點。
1.每個線程私有的,生命週期和線程相同。
2.每個方法在執行的同時創建一個棧幀。
3. 當進入一個方法時,這個方法需要在幀中分配的局部變量空間是完全確定的,在運行期間不會改變局部變量表的大小。
4.Java虛擬機規範中,對這個內存區域規定了兩種異常狀況。如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。如果虛擬機可以動態擴展,擴展時無法申請到足夠的內存空間,則會拋出OutOfMemoryError異常
三.本地方法棧
1.什麼是本地方法棧?
本地方法棧與Java虛擬機棧所發揮的作用非常相似,它們的區別不過是Java虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧爲虛擬機執行Native方法服務。
2.本地方法棧的作用與特點
1.每個線程私有的,生命週期和線程相同。
2.每個方法在執行的同時創建一個棧幀。
3. 當進入一個方法時,這個方法需要在幀中分配的局部變量空間是完全確定的,在運行期間不會改變局部變量表的大小。
4.Java虛擬機規範中,對這個內存區域規定了兩種異常狀況。如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。如果虛擬機可以動態擴展,擴展時無法申請到足夠的內存空間,則會拋出OutOfMemoryError異常
四.Java堆
1.什麼是Java堆?
存放對象的內存空間。
2.Java堆的作用
此內存區域的唯一目的是存放對象實例,幾乎所有的對象實例都是在Java堆分配內存。
3.Java堆的特點
1.Java堆是Java虛擬機所管理的內存空間中最大的一塊。
2.Java堆是所有線程共享的一塊內存區域。
3.在虛擬機啓動時創建。
4.所有對象的實例以及數組都要在堆上分配。
5.Java堆是垃圾收集器管理的主要區域。也被稱“GC堆”
6.Java堆可以處理物理上不連續的內存空間中,只要邏輯上連續即可。可以擴展,如果在隊中沒有內存完成實例分配,並且堆無法再擴展時,將拋出OOM。
五.方法區
1.什麼是方法區?
Java虛擬機規範中定義方法區是堆的一個邏輯部分。方法區中存放已經被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等。
2.方法區的特點
1.是各個線程共享的內存區域。
2.方法區中的信息一般需要長期存在,而且它又是堆的邏輯分區,因此用堆的劃分方法,我們把方法區稱爲老年代。
3.垃圾收集行爲在方法區較少出現,主要針對常量池的回收和對類型的卸載。
4.Java虛擬機規範對方法區的要求比較寬鬆。 和堆一樣,允許固定大小,也允許可擴展的大小,還允許不實現垃圾回收。