如下內容部分轉載於: CS-Notesjava
記錄正在執行的虛擬機字節碼指令的地址(若是正在執行的是本地方法則爲空)。git
ps:什麼是本地方法?github
本地方法是由其餘語言(如C、C++ 或其餘彙編語言)編寫,編譯成和處理器相關的代碼。本地方法保存在動態鏈接庫中,格式是各個平臺專用的,運行中的java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態庫,並調用這個方法。
學過計算機組成的同窗將不難理解,經過計數器尋找到下一條指令數組
每個線程都必須存在一個程序計數器,由於一個處理器在同一時間只能處理一個線程(對於單核處理器,或者多核處理器的一個內核)函數
經過程序計數器,來記錄每個線程所執行到的位置,方便線程直接的切換性能
虛擬機棧也是每一個線程私有的,它的生命週期與線程相同,虛擬機棧描述的是Java方法執行的內存模型spa
包括:局部變量表,操做數棧,動態連接,方法出口等信息線程
每個方法的從執行到完成,就表明着一個棧的在虛擬機棧中的入棧和出棧的過程3d
該區域可能拋出如下異常對象
StackOverflowError :當線程請求的棧深度超過最大值,如遞歸形成的方法屢次調用
OutOfMemoryError :棧進行動態擴展時若是沒法申請到足夠內存
本地方法(Native Method): 由其餘語言(如C、C++ 或其餘彙編語言)編寫,編譯成和處理器相關的代碼。本地方法保存在動態鏈接庫中,格
式是各個平臺專用的,運行中的java程序調用本地方法時,虛擬機裝載包含這個本地方法的動態庫,並調用這個方法。
具體用法和虛擬機棧相似,只不過它服務的對象爲本地方法,在Sun公司的HotSpot虛擬機中,就將把本地方法棧和虛擬機棧合二爲一
一樣會出現 StackOverflowError 和 OutOfMemoryError 錯誤
堆是一塊被Java全部線程共享的一塊內存區域,主要用於存放對象實例和數組
在堆中能夠分爲
咱們常說的 GC(Garbage Collected Heap) 說的就是整理這一塊的內存區域
堆的內存區域不須要連續,能夠動態的增長內存,增長失敗會拋出 OutOfMemoryError 異常。
能夠經過 -Xms 和 -Xmx 這兩個虛擬機參數來指定一個程序的堆內存大小,第一個參數設置初始值,第二個參數設置最大值。
java -Xms1M -Xmx2M HackTheJava
方法區和堆同樣,也誰被全部線程共享的內存區域,用於存儲已被虛擬機加載的類,常量,靜態變量,即時編譯器編譯後的代碼等數據
有一個別名 Non-Heap(非堆),在HotSpot虛擬機上人們習慣稱之爲 永久代(Permanent Generation)
方法區爲JVM的一個規範,定義爲存放某些數據,在不一樣的虛擬機中存在着不一樣的實現
由於在HotSpot虛擬機上,也存在這方法區的垃圾回收,因此稱爲永久代。
在永久代中常常會產生對永久代的回收不徹底致使內存泄漏爆出OutOfMemoryError的錯誤
爲了更容易管理方法區,在JDK8中,廢棄了永久代,改用元空間代替
把方法區移至到元空間中,元空間存儲於本地內存中,而不是在JVM虛擬機中
方法區是一個 JVM 規範,永久代與元空間都是其一種實現方式。
在 JDK 1.8 以後,原來永久代的數據被分到了堆和元空間中。元空間存儲類的元信息,靜態變量和常量池等放入堆中。
運行時的常量池是方法區的一部分,用於存放編譯期產生的各類字面量和符號引用
這部份內容將在類加載後進去方法區的運行時常量池存放
除了在編譯期生成的常量,還容許動態生成,例如 String 類的 intern()。
直接內存並非虛擬機運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域
可是這個區域的內存被頻繁使用,任然會形成OutOfMemoryError的異常
在 JDK 1.4 中新引入了 NIO 類,它可使用 Native 函數庫直接分配堆外內存,而後經過 Java 堆裏的 DirectByteBuffer 對象做爲這塊內存的引用進行操做。
這樣能在一些場景中顯著提升性能,由於避免了在堆內存和堆外內存來回拷貝數據。
PS: 直接內存不受Java堆大小的限制,可是既然是內存確定仍是會受本機總內存的影響