來源
https://blog.csdn.net/ns_code/article/details/17565503
http://www.cnblogs.com/sunada2005/p/3577799.html
first
大多數(shù) JVM 將內(nèi)存區(qū)域劃分為 Method Area(Non-Heap)(方法區(qū)) ,Heap(堆) , Program Counter Register(程序計數(shù)器) , VM Stack(虛擬機棧,也有翻譯成JAVA 方法棧的),Native Method Stack ( 本地方法棧 ),其中Method Area 和 Heap 是線程共享的 ,VM Stack,Native Method Stack 和Program Counter Register 是非線程共享的。為什么分為 線程共享和非線程共享的呢?請繼續(xù)往下看。
首先我們熟悉一下一個一般性的 Java 程序的工作過程。一個 Java 源程序文件,會被編譯為字節(jié)碼文件(以 class 為擴展名),每個java程序都需要運行在自己的JVM上,然后告知 JVM 程序的運行入口,再被 JVM 通過字節(jié)碼解釋器加載運行。那么程序開始運行后,都是如何涉及到各內(nèi)存區(qū)域的呢?
概括地說來,JVM初始運行的時候都會分配好 Method Area(方法區(qū)) 和Heap(堆) ,而JVM 每遇到一個線程,就為其分配一個 Program Counter Register(程序計數(shù)器) , VM Stack(虛擬機棧)和Native Method Stack (本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數(shù)器)所占用的內(nèi)存空間也會被釋放掉。這也是為什么我把內(nèi)存區(qū)域分為線程共享和非線程共享的原因,非線程共享的那三個區(qū)域的生命周期與所屬線程相同,而線程共享的區(qū)域與JAVA程序運行的生命周期相同,所以這也是系統(tǒng)垃圾回收的場所只發(fā)生在線程共享的區(qū)域(實際上對大部分虛擬機來說知發(fā)生在Heap上)的原因。
second VM 內(nèi)存模型圖
方法區(qū)域存放了所加載的類的信息(名稱、修飾符等)、類中的靜態(tài)變量、類中定義為final類型的常量、類中的Field信息、類中的方法信息,當開發(fā)人員在程序中通過Class對象中的getName、isInterface等方法來獲取信息時,這些數(shù)據(jù)都來源于方法區(qū)域,同時方法區(qū)域也是全局共享的,在一定的條件下它也會被GC,當方法區(qū)域需要使用的內(nèi)存超過其允許的大小時,會拋出OutOfMemory的錯誤信息