深入理解JVM(一):JVM內存區域

JVM內存區域

Java虛擬機管理的內存包括幾個運行時數據內存:方法區、虛擬機棧、本地方法棧、堆、程序計數器,其中方法區和堆是由線程共享的數據區,其他幾個是線程隔離的數據區
JVM運行時數據區

1.1 程序計數器

程序計數器是一塊較小的內存,他可以看做是當前線程所執行的行號指示器。字節碼解釋器工作的時候就是通過改變這個計數器的值來選取下一條需要執行的字節碼的指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。如果線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果正在執行的是Native方法,這個計數器則爲空。此內存區域是唯一一個在Java虛擬機規範中沒有規定任何OutOfMemotyError情況的區域

1.2 Java虛擬機棧

虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個棧幀用於儲存局部變量表、操作數棧、動態鏈接、方法出口等信息。每個方法從調用直至完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。
棧內存就是虛擬機棧,或者說是虛擬機棧中局部變量表的部分
局部變量表存放了編輯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(refrence)類型和returnAddress類型(指向了一條字節碼指令的地址)
其中64位長度的long和double類型的數據會佔用兩個局部變量空間,其餘的數據類型只佔用1個。
Java虛擬機規範對這個區域規定了兩種異常狀況:如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常。如果虛擬機擴展時無法申請到足夠的內存,就會跑出OutOfMemoryError異常

1.3 本地方法棧

本地方法棧和虛擬機棧發揮的作用是非常類似的,他們的區別是虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則爲虛擬機使用到的Native方法服務
本地方法棧區域也會拋出StackOverflowError和OutOfMemoryErroy異常

1.4 Java堆

堆是Java虛擬機所管理的內存中最大的一塊。Java堆是被所有線程共享的一塊內存區域,在虛擬機啓動的時候創建,此內存區域的唯一目的是存放對象實例,幾乎所有的對象實例都在這裏分配內存。所有的對象實例和數組都在堆上分配
Java堆是垃圾收集器管理的主要區域。Java堆細分爲新生代和老年代
不管怎樣,劃分的目的都是爲了更好的回收內存,或者更快地分配內存
Java堆可以處於物理上不連續的內存空間中,只要邏輯上是連續的即可。如果在堆中沒有完成實例分配,並且堆也無法在擴展時將會拋出OutOfMemoryError異常

1.5 方法區

方法區它用於儲存已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據
除了Java堆一樣不需要連續的內存和可以選擇固定大小或者可擴展外,還可以選擇不實現垃圾收集。這個區域的內存回收目標主要是針對常量池的回收和對類型的卸載
當方法區無法滿足內存分配需求時,將拋出OutOfMemoryErroy異常

1.6 運行時常量池

它是方法區的一部分。Class文件中除了有關的版本、字段、方法、接口等描述信息外、還有一項信息是常量池,用於存放編輯期生成的各種字面量和符號引用,這部分內容將在類加載後進入方法區的運行時常量池中存放
Java語言並不要求常量一定只有編輯期才能產生,也就是可能將新的常量放入池中,這種特性被開發人員利用得比較多的便是String類的intern()方法
當常量池無法再申請到內存時會拋出OutOfMemoryError異常

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