堆:在Java虛擬機中,堆(Heap)是可供各條線程共享的運行時內存區域,也是供全部類實例和數組對象分配內存的區域。Java堆在虛擬機啓動的時候就被建立,它存儲了被自動內存管理系統(Automatic Storage Management System,也便是常說的「Garbage Collector(垃圾收集器)」)所管理的各類對象,這些受管理的對象無需,也沒法顯式地被銷燬,它們的內存管理交給系統全權負責。堆是一塊大小比較隨意的區域,咱們並不須要知道它詳細的大小,也並不要求它是一塊連續的區域,甚至都不用去管理它,它惟一的做用就是用來存放對象的實例,絕大部分java的對象實例都保存在堆中。可是既然說是絕大部分,那麼確定就存在例外。好比:當程序員用這樣的方式建立一個String類時 java
String str = "我是特例 !!!";
,這個類的實例就保存在棧中。倒不是由於它被賦予的值特殊,而是String類比較特殊。 程序員
棧:java虛擬機中的棧與線程同時建立,每一個線程都擁有本身私有的棧。棧中用來保存局部變量和一些過程結果。其實這些變量都是以一種棧幀的形式在存取,棧只能識別和管理棧幀。棧幀(Frame)是用來存儲數據和部分過程結果的數據結構,同時也被用來處理本地變量表、操做棧、動態連接、方法出入口等信息,棧幀隨着方法調用而建立,隨着方法結束而銷燬。那麼棧中到底存儲的是什麼東西呢?這些棧幀仍是由基本類型和引用類型組成的,由於引用的對象都保存在堆中,因此棧中保存的就是基本的數據類型組成的數據。 數組
public class PrintSth{ private int num = 1;//基本類型的變量① private String sth = "what?"//非new定義的String字符串② public boolean print(){//方法的聲明③ System.out.println("The number is "+num); System.out.println("The something is"+sth); return true;//返回值④ } public static void main(String[] args){//參數⑤ PrintSth ps = new PrintSth();//類的聲明⑥和對象的實例⑦ if(ps.print()){ System.out.println("i know what were you said!"); } } }如上的代碼:哪些部分是存儲在堆中哪些部分是存儲在棧中的呢?
堆中:⑦ 棧中:①②③④⑤⑥ 那麼其餘的那些代碼存儲在哪裏呢?答案是方法區(Method Area),其實方法區也是堆的一塊區域。 數據結構
堆和棧優缺點總結: spa
堆:動態分配內存,使用比較方便,堆的生命週期不用咱們本身去管理,儘管使用便可,建立及回收的工做系統都會自動進行。可是由於是動態分配內存,並且系統須要檢查堆中的對象是否應該銷燬,因此速度比較慢。 線程
棧:存取速度較快,僅次於CPU中的寄存器,棧中的數據能夠共享(如:int a, b; a = 3, b = 3.則a和b所指的地址是同樣的,也就是說棧中只有一個3 )。存在棧中的數據的大小和生命週期必須是已知的,因此缺少必定的靈活性。 code