原文更詳細:http://www.javashuo.com/article/p-poxahysy-cd.html
程序計數器:
一、一塊較小的內存空間,做用是當前線程所執行的字節碼的行號指示器。(Java 虛擬機的多線程是經過線程輪流切換並分配處理器執行時間的方式來實現的,在任何一個肯定的時刻,一個處理器(對於多核處理器來講是一個內核)只會執行一條線程中的指令。)
二、若是線程正在執行的是一個Java 方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若是正在執行的是Natvie 方法(java內部的方法可能用其它語言編寫,經過java調用,能夠自定義native方法,好比調用C語言方法,參考地址:java調用c語言方法),這個計數器值則爲空(Undefined)。
三、此內存區域是惟一一個在Java 虛擬機規範中沒有規定任何OutOfMemoryError 狀況的區域。html
java虛擬機棧
一、與程序計數器同樣,Java 虛擬機棧(Java Virtual Machine Stacks)也是線程私有的,它的生命週期與線程相同。
二、每一個方法被執行的時候都會同時建立一個棧幀(Stack Frame ①)用於存儲局部變量表、操做棧、動態連接、方法出口等信息。
三、每個方法被調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。
四、常有人把Java 內存區分爲堆內存(Heap)和棧內存(Stack),這種分法比較粗糙,Java 內存區域的劃分實際上遠比這複雜。
五、兩種異常情況:若是線程請求的棧深度大於虛擬機所容許的深度,將拋出StackOverflowError 異常;若是虛擬機棧能夠動態擴展(當前大部分的Java 虛擬機均可動態擴展,只不過Java 虛擬機規範中也容許固定長度的虛擬機棧),當擴展時沒法申請到足夠的內存時會拋出OutOfMemoryError 異常。
java.lang.StackOverflowError java.lang.OutOfMemoryError: Java heap space
java
本地方法棧 一、本地方法棧(Native Method Stacks)與虛擬機棧所發揮的做用是很是類似的,其區別不過是虛擬機棧爲虛擬機執行Java 方法(也就是字節碼)服務,而本地方法棧則是爲虛擬機使用到的Native 方法服務。
二、本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError算法
Java 堆 一、對於大多數應用來講,Java 堆(Java Heap)是Java 虛擬機所管理的內存中最大的一塊。
二、全部的對象實例以及數組都要在堆上分配①,可是隨着JIT 編譯器的發展與逃逸分析技術的逐漸成熟,棧上分配、標量替換②優化技術將會致使一些微妙的變化發生,全部的對象都分配在堆上也漸漸變得不是那麼「絕對」了。
三、Java 堆是垃圾收集器管理的主要區域,所以不少時候也被稱作「GC 堆」
四、收集器基本都是採用的分代收集算法,因此Java 堆中還能夠細分爲:新生代和老年代;再細緻一點的有Eden 空間、From Survivor 空間、To Survivor 空間等。 五、Java 堆能夠處於物理上不連續的內存空間中,只要邏輯上是連續的便可,就像咱們的磁盤空間同樣。
六、若是在堆中沒有內存完成實例分配,而且堆也沒法再擴展時,將會拋出OutOfMemoryError 異常。數組
方法區
一、方法區(Method Area)與Java 堆同樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
二、習慣在HotSpot 虛擬機上開發和部署程序的開發者來講,不少人願意把方法區稱爲「永久代」(Permanent Generation),本質上二者並不等價。
三、根據Java 虛擬機規範的規定,當方法區沒法知足內存分配需求時,將拋出OutOfMemoryError 異常。多線程
運行時常量池
一、運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量池(Constant PoolTable),用於存放編譯期生成的各類字面量和符號引用,這部份內容將在類加載後存放到方法區的運行時常量池中。
二、既然運行時常量池是方法區的一部分,天然會受到方法區內存的限制,當常量池沒法再申請到內存時會拋出OutOfMemoryError 異常。優化
直接內存
直接內存(Direct Memory)並非虛擬機運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域,可是這部份內存也被頻繁地使用,並且也可能致使OutOfMemoryError 異常出現。spa
未完待續……線程