簡單通俗的講,一個完整的Java程序運行過程會涉及如下內存區域:html
(1) 寄存器:它直接位於處理器內部 Java中不能直接控制寄存器 java
這是最快的保存區域,由於它位於和其餘全部保存方式不一樣的地方:處理器內部。然而,寄存器的數量十分有限,因此寄存器是根據須要由編譯器分配。咱們對此沒有直接的控制權,也不可能在本身的程序裏找到寄存器存在的任何蹤影。面試
(2) 堆棧:位於通用RAM中,經過堆棧的指針從處理器得到直接支持,堆棧指針向下移動,則分配新的內存,向上移動則釋放內存,這樣作十分高效。可是建立過程當中,java系統必須知道堆棧中全部項的確切生命週期,這一約束限制了程序的靈活性。基本類型和對象引用就存在其中,可是java對象除外。數據庫
駐留於常規RAM(隨機訪問存儲器)區域,但可經過它的「堆棧指針」得到處理的直接支持。堆棧指針若向下移,會建立新的內存;若向上移,則回什邡那些內存。這是一種特別快、特別有效的數據保存方式,僅次於寄存器。建立程序時,java編譯器必須準確的知道堆棧內保存的全部數據的「長度」以及「存在時間」。這些因爲他必須生成相應的代碼,以便於向上和向下移動指針。這一限制無疑影響了程序的靈活性,因此儘管有些java數據要保存在堆棧裏-特別是對象的句柄,可是java對象並不放到其中。安全
(3) 堆:一種通用的內存池,用於存放全部的java對象。缺點就是爲了靈活性而增長了時間。jvm
一種常規用途的內存池,其中保存了java對象。和堆棧不一樣,「內存堆」或「堆」最吸引人的地方在於編譯器沒必要知道要分配多少存儲空間,也不知道存儲的數據要在堆裏停留多長時間。所以,用堆保存數據時會獲得更大的靈活性。要求建立一個對象時,只須要new命令編制相關的代碼便可。執行這些代碼時,會在堆裏自動進行數據的保存。固然,爲了達到這種靈活性,必然會付出必定的代價:在堆裏分配存儲空間會花掉更長的時間。.net
(4) 靜態存儲指針
這兒的「靜態」(static)是指「位於固定位置」(也放在RAM裏)。程序運行期間,靜態存儲的數據將隨時等待調用。可用static關鍵字之處一個對象的特定元素是靜態的。但Java對象自己永遠都不會置入靜態存儲空間。htm
(5) 常數存儲對象
常數值一般直接置於程序代碼內部。這樣作是安全的,由於他們永遠都不會改變。有的常數須要嚴格的保護,因此可考慮將他們置入只讀存儲器(ROM)
(6) 非RAM存儲:兩個基本的例子就是流對象和持久化對象。流對象中,對象將被轉化成字節流;持久化對象中,對象被存在於磁盤上,如數據庫。
若數據徹底獨立於一個程序以外,則程序不運行時奶可存在,並在程序的控制範圍以外。其中兩種最主要的例子即是「流式對象」和「固定對象」。對於流式對象,對象會變成字節流,一般會發給另外一臺機器。而對於固定對象、對象保存在磁盤中。即使程序停止運行,他們仍可保持本身的狀態不變。對於這些類型的數據存儲,一個特別有用的技巧就是他們可以存在於其餘媒體中,一旦須要,設置能將他們回覆成普通的、基於RAM的對象。
以上都是概念性的東西,能夠參考下列博客中,有實踐反應的每一步,更加理解這些內存分配。
Java內存分配全面淺析:http://blog.csdn.net/yangyuankp/article/details/7651251
java內存分配研究:http://www.blogjava.net/Jack2007/archive/2008/05/21/202018.html
Java常量池詳解之一道比較蛋疼的面試題:http://www.cnblogs.com/DreamSea/archive/2011/11/20/2256396.html
jvm常量池:http://www.cnblogs.com/wenfeng762/archive/2011/08/14/2137820.html
深刻Java核心 Java內存分配原理精講:http://developer.51cto.com/art/201009/225071.htm