JAVA虛擬機運行時會將JVM使用的內存劃分爲不一樣的區域,每一個區域負責不一樣的功能,以及各個區域的建立,銷燬都各不相同。 java
下圖是JVM運行時內存數據區的劃分, eclipse
圖一、JVM運行時數據區 優化
一、程序計數器 spa
每一個線程都擁有一個獨立的程序計數器,用於記錄當前線程所要執行的字節碼指令,該類內存區域爲「線程私有」內存。 .net
二、虛擬機棧 線程
該區域也有人稱爲棧內存(對應java堆內存),這個叫法不徹底正確,但能夠便於理解。 code
該區域也是線程私有的,而且與線程的生命週期相同。 對象
主要負責方法執行的內存部分,在每一個方法執行時都會建立一個棧針存儲局部變量,操做數等方法相關信息,每一次方法的調用到完成,都對應一個棧針在虛擬機棧中出入棧的過程。 blog
該區域會拋出stackOverFlowError和OutOfMemoryError錯誤 生命週期
stackOverFlowError 是線程請求的棧深度大於虛擬機容許的深度,以下面的代碼
public static void main(String[] args) { testStackOverFlow(); } public static void testStackOverFlow(){ System.out.println("stackOverFLow"); testStackOverFlow(); }
OutOfMemoryError錯誤就是棧空間溢出,好比局部變量過多,佔用內存過大,都會產生就不舉例說明
三、本地方法棧
和虛擬機棧相似,只是負責本地Native方法,也會拋出stackOverFlowError和OutOfMemoryError錯誤,如IO中經常使用的文件讀寫操做的Native方法,多是C語言或者其餘語言的實現。
四、JAVA堆(JAVA Heap),GC堆
JAVA堆是JAVA虛擬機管理的內存,最大,最重要的部分,是全部線程共享的區域,
也是GC(垃圾回收)的主要回收部分,
再進行劃分能夠分爲新生代,老生代(老年代);新生代能夠劃分爲:Eden,From Survivor,To Survivor
主要存放對象實例,能夠經過配置,設置不一樣代的大小和垃圾回收策略,不少優化也在堆上進行實現。
堆的詳細介紹:http://www.begincode.net/blog/47
該區域會拋出 OutOfMemoryError異常
五、方法區(Method Area),非堆,永久代
該區域也是線程共享的內存區域,該區域也會進行垃圾回收,但能夠忽略不計,由於效果很難使人滿意
主要存儲虛擬機加載的類信息,常量,靜態變量等
該區域會拋出OutOfMemoryError異常,主要是啓動時須要加載的類,常量,靜態變量等信息特別多,超過了該區域設置的內存空間,就會拋出異常,
能夠看看eclipse內存設置,若是將內存設置特別小就會拋出該內存溢出異常
http://www.begincode.net/blog/50
運行時常量池:屬於方法區的一部分,主要存儲運行時常量,如String的intern方法產生的字符串常量。
六、直接內存
直接內存沒有在圖中顯示,覺得他並非虛擬機運行時數據區的一部分,不歸虛擬機管理,但該內存區域也會出現OutOfMemoryError異常,
該區域使用主要是在NIO的緩衝區的使用,會用到系統直接內存,由於是經過本地方法分配的內存,當本機沒法分配更多的內存時就會拋出內存溢出異常