深度理解JVM-----運行時數據區域

如下內容部分轉載於: CS-Notesjava

程序計數器(Program Counter Register)

記錄正在執行的虛擬機字節碼指令的地址(若是正在執行的是本地方法則爲空)。git

ps:什麼是本地方法?github

本地方法是由其餘語言(如C、C++ 或其餘彙編語言)編寫,編譯成和處理器相關的代碼。本地方法保存在動態鏈接庫中,格式是各個平臺專用的,運行中的java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態庫,並調用這個方法。

學過計算機組成的同窗將不難理解,經過計數器尋找到下一條指令數組

每個線程都必須存在一個程序計數器,由於一個處理器在同一時間只能處理一個線程(對於單核處理器,或者多核處理器的一個內核)函數

經過程序計數器,來記錄每個線程所執行到的位置,方便線程直接的切換性能


Java虛擬機棧(Java Virtual Machine Stacks)

虛擬機棧也是每一個線程私有的,它的生命週期與線程相同,虛擬機棧描述的是Java方法執行的內存模型spa

包括:局部變量表,操做數棧,動態連接,方法出口等信息線程

每個方法的從執行到完成,就表明着一個棧的在虛擬機棧中的入棧和出棧的過程3d

該區域可能拋出如下異常對象

StackOverflowError :當線程請求的棧深度超過最大值,如遞歸形成的方法屢次調用

OutOfMemoryError :棧進行動態擴展時若是沒法申請到足夠內存


本地方法棧(Native Method Stack)

本地方法(Native Method): 由其餘語言(如C、C++ 或其餘彙編語言)編寫,編譯成和處理器相關的代碼。本地方法保存在動態鏈接庫中,格

式是各個平臺專用的,運行中的java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態庫,並調用這個方法。

具體用法和虛擬機棧相似,只不過它服務的對象爲本地方法,在Sun公司的HotSpot虛擬機中,就將把本地方法棧和虛擬機棧合二爲一

一樣會出現 StackOverflowErrorOutOfMemoryError 錯誤


堆(Heap)

堆是一塊被Java全部線程共享的一塊內存區域,主要用於存放對象實例和數組

在堆中能夠分爲

  • 新生代(Young Generation)
  • 老年代(Old Generation)

咱們常說的 GC(Garbage Collected Heap) 說的就是整理這一塊的內存區域

堆的內存區域不須要連續,能夠動態的增長內存,增長失敗會拋出 OutOfMemoryError 異常。

能夠經過 -Xms 和 -Xmx 這兩個虛擬機參數來指定一個程序的堆內存大小,第一個參數設置初始值,第二個參數設置最大值。

java -Xms1M -Xmx2M HackTheJava

方法區(Method Area)

方法區和堆同樣,也誰被全部線程共享的內存區域,用於存儲已被虛擬機加載的類,常量,靜態變量,即時編譯器編譯後的代碼等數據

有一個別名 Non-Heap(非堆),在HotSpot虛擬機上人們習慣稱之爲 永久代(Permanent Generation)

方法區爲JVM的一個規範,定義爲存放某些數據,在不一樣的虛擬機中存在着不一樣的實現

由於在HotSpot虛擬機上,也存在這方法區的垃圾回收,因此稱爲永久代。

在永久代中常常會產生對永久代的回收不徹底致使內存泄漏爆出OutOfMemoryError的錯誤

爲了更容易管理方法區,在JDK8中,廢棄了永久代,改用元空間代替

方法區移至到元空間中,元空間存儲於本地內存中,而不是在JVM虛擬機

方法區是一個 JVM 規範,永久代與元空間都是其一種實現方式。

在 JDK 1.8 以後,原來永久代的數據被分到了堆和元空間中。元空間存儲類的元信息,靜態變量和常量池等放入堆中。


運行時的常量池(Runtime Constant Pool)

運行時的常量池是方法區的一部分,用於存放編譯期產生的各類字面量和符號引用

這部份內容將在類加載後進去方法區的運行時常量池存放

除了在編譯期生成的常量,還容許動態生成,例如 String 類的 intern()。


直接內存(Direct Memory)

直接內存並非虛擬機運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域

可是這個區域的內存被頻繁使用,任然會形成OutOfMemoryError的異常

JDK 1.4 中新引入了 NIO 類,它可使用 Native 函數庫直接分配堆外內存,而後經過 Java 堆裏的 DirectByteBuffer 對象做爲這塊內存的引用進行操做。

這樣能在一些場景中顯著提升性能,由於避免了在堆內存和堆外內存來回拷貝數據。

PS: 直接內存不受Java堆大小的限制,可是既然是內存確定仍是會受本機總內存的影響

相關文章
相關標籤/搜索