Java虛擬機學習筆記-運行時數據區(內存區)

Java虛擬機在執行java程序過程中把內存劃分成不同的數據區域:比如常見的堆棧、方法區、靜態域、常量池等。以下是java運行時的數據區域圖解:
這裏寫圖片描述

1、程序計數器
在運行時數據區中程序計數器是一塊分配較小內存的空間,它的主要功能可以描述爲jvm字節碼編譯的位置記錄器,字節碼解釋器工作時就是通過改變此程序計數器的值來選取下一條需要執行的字節碼指令。
java虛擬機的多線程是通過線程之間的輪流切換並分配處理器執行時間的方式來實現。在任何確定的時刻,一個處理器只會執行一條線程中的指令。因此這樣爲了能在不同線程之間的切換並回到正確位置,可以知道每個線程都必須有一個獨立 的程序計數器。。並且各個線程之間的程序計數器互相獨立。在參考書中也把這類內存區域叫做“”線程私有“”的內存。
程序計數器的邏輯爲:
1.如果線程正在執行的是一個java方法,那麼計數器記錄的是正在執行的虛擬機字節碼指令地址
2.如果執行的native方法,計數器當中的內容應當是空(undefined) native方法就是原生態方法,由於java語言本身不能對操作系統底層進行訪問和操作,但是可以通過JNI接口調用其他語言來實現對底層的訪問。這個方法就是native方法。
3.此內存區域在java的虛擬機規範當中是唯一一個沒有規定OutOfMemoryError的區域

2、java虛擬機棧
在這裏是說明一下,java棧總是和線程關聯在一起,每當創建一個線程時,JVM就會爲這個線程創建一個對應的java棧。在這個java棧中又會包含多個棧幀,每運行一個方法就創建一個棧幀,用於存儲局部變量表(用來存儲編譯器可知的各種基本數據類型和對象引用和returnAddress)、操作棧、方法返回值等。每一個方法從調用直至執行完成的過程,就對應一個棧幀在java棧中入棧到出棧的過程。所以java棧是現成私有的。所以在java棧中的對象和數據總是跟隨線程生,伴隨線程滅的(自動回收垃圾)。也就是說後面的垃圾回收機制在Java棧中就不存在。在棧中主要出現的異常爲:1.當線程請求的棧深度超過虛擬機所允許的棧深度,拋出StackOverflowError異常;2.當棧擴展(棧是可以動態擴展的)無法申請到足夠的內存時拋出OOM(OutOfMemoryErroor)異常。

3.Java堆:在java內存管理中堆(heap)是java虛擬機內存分配空間中最大的一塊,它的目的就是存儲新建的對象實例,所有的對象實例或者數組都(考慮絕對,忽略JIT編譯器的情況)在這裏分配內存空間。所以java堆對於所有線程是共有的。當然後面要說的方法區也是線程共享的。這就決定了垃圾回收器的主要工作範圍就是堆和方法區。這裏主要出現的異常爲:如果堆內存無法滿足實例的分配,並且堆無法再進行擴展時將拋出OOM(OutOfMemoryErroor)異常。

4.方法區(Method Area):前面說到過,它和堆都是線程共享的。方法區從字面意思上可以知道它的功能,用來存儲類信息。包括常量池、靜態變量、構造函數等。雖然JVM規範把方法區描述爲堆的一個邏輯部分, 但它卻有個別名non-heap(非堆)。方法區還包含一個運行時常量池。其存在的主要異常爲:當方法區無法滿足內存分配需求時,將拋出OOM(OutOfMemoryErroor)異常。

5.本地方法棧(Native Method Stack):和java棧的作用差不多,只不過是爲JVM使用到的native方法服務的。也是會出現StackOverflowError和OutOfMemoryError異常。

6.運行時常量池(Constant Pool Table):這是在方法區中的一個重要概念。常量池是java的class結構中的一部分。用於存放編譯生成的各種字面量和字符常量、符號引用等。在類加載之後會把這些加載到運行時常量池中。class文件的結構有:魔數(用來識別class文件的特殊表示)、版本號、字段、方法、接口的信息描述,還有常量池(字面量和符號引用)。

在瞭解了內存劃分之後,記錄一下內存的分配機制:編譯時就能夠確定的內存就是靜態內存,即內存是固定的,系統一次性分配,比如int類型變量;
動態內存分配就是在程序執行時才知道要分配的存儲空間大小,比如java對象的內存空間。根據上面我們知道,java棧、程序計數器、本地方法棧都是線程私有的,線程生就生,線程滅就滅,棧中的棧幀隨着方法的結束也會撤銷,內存自然就跟着回收了。所以這幾個區域的內存分配與回收是確定的,我們不需要管的。但是java堆和方法區則不一樣,我們只有在程序運行期間才知道會創建哪些對象,所以這部分內存的分配和回收都是動態的。一般我們所說的垃圾回收也是針對的這一部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章