Java虛擬機運行時內存區域分爲程序計數器、虛擬機棧、本地方法棧、堆、方法區等。java
程序計數器:線程私有,用來指示須要執行的下一條字節碼指令,若是當前正在執行native方法,則爲空(Undefined),在虛擬機規範中惟一沒有規定OOM Error的區域。
函數
虛擬機棧:線程私有,每調用一個方法,都建立一個棧幀壓入虛擬機棧,用來存儲局部變量表等信息,方法執行完後相應棧幀出棧。局部變量表存儲的是編譯期可知的各類基礎類型和對象引用以及returnAddress(指向一條字節碼指令的地址),其中long和double類型佔2個局部變量空間,其他類型佔用1個。局部變量表大小在運行時不會改變。若是棧深度超過容許值,則拋出StackOverflowError,若是擴展時沒法申請足夠內存,則拋出OutOfMemoryError。
spa
本地方法棧:線程私有,與虛擬機棧相似,只不過是在調用native方法時使用。
操作系統
堆:公有,通常來講是最大的一塊內存區域,幾乎全部的對象實例都存儲在堆上。若是堆中空間不夠,並且也無法繼續擴展,將拋出OutOfMemoryError。
線程
方法區:公有,主要存儲加載的類信息、常量、靜態變量。若是空間不足,將拋出OutOfMemoryError。
code
運行時常量池:公有,是方法區的一部分,主要存放常量,在運行時能夠動態加入新的常量(好比String的intern()方法)。若是空間不足,將拋出OutOfMemoryError。對象
直接內存:公有,在堆之外經過native函數分配的內存,雖然不受堆大小制約,可是仍然不能超過操做系統和物理內存的限制,若是空間不足,將拋出OutOfMemoryError。內存
例如以下的代碼:虛擬機
Object obj=new Object();
其中Object obj會在本地變量表中存儲obj變量,new Object()會在堆上分配一個Object實例的空間,而Object類的信息則載入到方法區中。
編譯