先上一張jvm的圖java
能夠分爲線程共享,和線程獨有的兩塊內存。數據結構
1、程序計數器:一塊較小的內存空間,當前線程執行字節碼行號的指示器。也就是線程下一行須要幹什麼事,執行什麼代碼。若是線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若是正在執行的是Native方法,這個計數器值則爲空(Undefined)多線程
補充:一個cpu(單核,一個處理器)在某一個時刻只能執行一條線程中的指令,因此多線程是線程輪流切換並分配處理器執行時間來實現的,爲了能在切換的時候恢復正確的執行位置,每一個線程要保存當前線程執行的位置,也就程序計數器私有了。jvm
2、虛擬機棧:描述的是java方法執行的內存模型,每一個方法執行都會建立一個棧幀,存放局部變量,方法出口等信息。每個方法調用到執行完成就是一個棧幀從入棧到出棧的過程。spa
一、局部變量存放的是編譯期可知的基本數據類型(boolean,byte,chat,short,int,float,long,double),對象引用(reference, 指向對象起始地址的引用指針),returnAddress(指向了一條字節碼指令的地址)線程
二、局部變量所需的內存空間在編譯時期就分配完成,在運行時期不會改變大小。指針
三、這個區域會出現兩個異常,StackOverflowError,OutOfMemoryError對象
StackOverflowError:當線程請求的棧深度大於虛擬機所容許的深度。(固定長度的虛擬機棧)接口
OutOfMemoryError:當虛擬機棧動態擴展(大部分java虛擬機都支持動態擴展),若是擴展時申請不到內存就拋此異常內存
3、本地方法棧:做用和虛擬機棧同樣,區別是虛擬機爲java方法服務,本地方法棧是爲native方法服務,虛擬機規範中對本地方法棧沒有語言,數據結構,使用方式的限制,能夠有虛擬機自由實現,有些虛擬機就把他們合併。 這個區域也會拋出StackOverflowError,OutOfMemoryError異常。
4、堆:此部分是線程共享的,在虛擬機啓動的時候建立,存放對象的實例,數據,是jvm最大的一塊,垃圾回收器也是對此部份內存的回收。若是堆中沒有完成實例分配,不能擴展的時候,會拋OutOfMemoryError。
5、方法區:存放被虛擬機加載的類信息(方法,字段),常量,靜態變量。
在方法區中有一個很是重要的部分就是運行時常量池,用於存放編譯期生成的各類字面量和符號引用,它是每個類或接口的常量池的運行時表示形式,在類和接口被加載到JVM後,對應的運行時常量池就被建立出來。固然並不是Class文件常量池中的內容才能進入運行時常量池,在運行期間也可將新的常量放入運行時常量池中,好比String的intern方法。