JVM虛擬機運行時數據區域的理解

Java虛擬機在執行Java程序的過程中會把它所管理的內存劃分爲若干個不同的數據區域。這些區域都有各自的用戶,以及創建和銷燬的時間,有的區域隨着虛擬機進程的啓動而存在,有些區域則依賴用戶線程的啓動和結束而創建和銷燬。

1.程序計數器

程序計數器(program Counter Register)是一塊較小的內存空間,它可以看作是當前線程所執行的字節碼的行號指示器。在虛擬機的概念模型裏(僅僅是概念模型,各種虛擬機可能會通過一些更加高效的方式去實現),字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支,循環,跳轉,異常處理,線程恢復等基礎功能都需要依賴這個計數器來完成。

由於java虛擬機的多線程是通過線程輪流切換並分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器(對於多核處理器來說是一個內核)都會執行一條線程中的指令。因此爲了線程切換後能恢復到正確的執行位置,每條線程都需要一個獨立的程序計數器,各個線程之間計數器互不影響,獨立存儲,我們稱這類內存區域爲線程私有的內存。

如果線程正在執行的是一個Java方法,這個計數器記錄的是正在執行虛擬機字節碼指令的地址;如果正在執行的是Native方法,這個計數器值則爲空(Undefined)。此內存區域是唯一一個在java虛擬機中沒用規定任何outOfMemoryErroe情況的區域。

2.Java棧

與程序計數器一樣,java棧也是線程私有的,他的生命 週期與線程相同。虛擬機棧描述的是java內存模型。每個方法在執行的同時都會創建一個棧幀,每個棧幀對應一個被調用的方法,在棧幀中包括局部變量表(Local Variables)、操作數棧(Operand Stack),動態鏈接,方法出口等信息。當線程執行一個方法時,就會隨之創建一個對應的棧幀,並將建立的棧幀壓棧。當方法執行完畢之後,便會將棧幀出棧。因此可知,線程當前執行的方法所對應的棧幀必定位於Java棧的頂部。講到這裏,大家就應該會明白爲什麼 在 使用 遞歸方法的時候容易導致棧內存溢出的現象了以及爲什麼棧區的空間不用程序員去管理了(當然在Java中,程序員基本不用關係到內存分配和釋放的事情,因爲Java有自己的垃圾回收機制),這部分空間的分配和釋放都是由系統自動實施的。

局部變量表,顧名思義,想必不用解釋大家應該明白它的作用了吧。就是用來存儲方法中的局部變量(包括在方法中聲明的非靜態變量以及函數形參)。對於基本數據類型的變量,則直接存儲它的值,對於引用類型的變量,則存的是指向對象的引用。局部變量表的大小在編譯器就可以確定其大小了,因此在程序執行期間局部變量表的大小是不會改變的

在java虛擬機規範中,對這個區域規定了兩種異常情況:如果縣城請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常;如果虛擬機棧可以動態擴展而擴展時無法申請到足夠的內存,就會拋出OutOfMemoryError異常。

3.本地方法棧

本地方法棧與Java棧的作用和原理非常相似。區別只不過是Java棧是爲執行Java方法服務的,而本地方法棧則
是爲執行本地方法(Native Method)服務的。在JVM規範中,並沒有對本地方發展的具體實現方法以及數據結構作
強制規定,虛擬機可以自由實現它。在HotSopt虛擬機中直接就把本地方法棧和Java棧合二爲一。

4.Java堆

java堆是Java虛擬機所管理內存中最大的一塊。java堆是所有線程所共享的一塊內存區域。java堆是垃圾收集器管理的主要區域,因此很多時候也被稱作"GC堆"從內存回收的角度來看,由於現在收集器基本都採用分帶收集算法,所以java堆中還可以細分爲:新生代和老年代;

5.方法區

方法區與java堆一樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯後的代碼等數據。也有人把方法區的人稱爲永久代,但是實際上兩者並不等價。僅僅是因爲HotSpot虛擬機的設計團隊選擇把GC分代收集擴展至方法區。

6.運行時常量池

運行時常量池是方法區的一部分。Class文件中除了有類的版本,字段,方法,接口等信息外,還有一項信息是常量池,用於存放編譯期生成的各種字面量和符號引用,這部分內存將在類加載後進入方法去的運行時常量池中存放。

7.直接內存

直接內存並不是虛擬機運行時數據區的一本分,也不是java虛擬機規範中定義的內存區域。這是NIO類,使用Native函數庫直接分配堆外內存,然後通過一個存儲在java堆中的DirectByte Buffer對象作爲這塊內存的引用進行操作。這樣能在一些場景中顯著提高性能。

發佈了181 篇原創文章 · 獲贊 300 · 訪問量 69萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章