一。------------------------------------------------------------
堆--用new建立,垃圾自動回收負責回收
1、堆是一個"運作時"資料區,類執行個體化的對象就是從堆上去配置設定空間的;
2、在堆上配置設定空間是通過"new"等指令建立的;
3、Java針對堆的操作和C++的差別就是,Java不需要在空間不用的時候來顯式的釋放;
4、Java的堆是由Java的垃圾回收機制來負責處理的,堆是動态配置設定記憶體大小,垃圾收集器可以自動回收不再使用的記憶體空間。
5、但缺點是,因為在運作時動态配置設定記憶體,是以記憶體的存取速度較慢。
例如:
|
棧--存放基本資料類型,速度快
1、棧中主要存放一些基本類型的變量(int, short, long, byte, float, double, boolean, char)和對象句柄;
2、棧的存取速度比堆要快;
3、棧資料可以共享;
4、棧的資料大小與生存期必須是确定的,缺乏靈活性。
例如:
int a = 3;
二 。非常重要-------------------------------------
VM棧是運作時的機關,而JVM堆是存儲的機關。
JVM棧解決程式的運作問題,即程式如何執行,或者說如何處理資料;JVM堆解決的是資料存儲的問題,即資料怎麼放、放在哪兒。
JVM堆中存什麼?JVM棧中存什麼?
JVM堆中存的是對象。JVM棧中存的是基本資料類型和JVM堆中對象的引用。一個對象的大小是不可估計的,或者說是可以動态變化的,但是在JVM棧中,一個對象隻對應了一個4btye的引用(JVM堆JVM棧分離的好處:))。
為什麼不把基本類型放JVM堆中呢?因為其占用的空間一般是1~8個位元組——需要空間比較少,而且因為是基本類型,是以不會出現動态增長的情況——長度固定,是以JVM棧中存儲就夠了,如果把他存在JVM堆中是沒有什麼意義的(還會浪費空間,後面說明)。可以這麼說,基本類型和對象的引用都是存放在JVM棧中,而且都是幾個位元組的一個數,是以在程式運作時,他們的處理方式是統一的。但是基本類型、對象引用和對象本身就有所差別了,因為一個是JVM棧中的資料一個是JVM堆中的資料。最常見的一個問題就是,Java中參數傳遞時的問題。
Java中的參數傳遞時傳值呢?還是傳引用?
要說明這個問題,先要明确兩點:
1.不要試圖與C進行類比,Java中沒有指針的概念
2.程式運作永遠都是在JVM棧中進行的,因而參數傳遞時,隻存在傳遞基本類型和對象引用的問題。不會直接傳對象本身。
明确以上兩點後。Java在方法調用傳遞參數時,因為沒有指針,是以它都是進行傳值調用(這點可以參考C的傳值調用)。是以,很多書裡面都說Java是進行傳值調用,這點沒有問題,而且也簡化的C中複雜性。
但是傳引用的錯覺是如何造成的呢?在運作JVM棧中,基本類型和引用的處理是一樣的,都是傳值,是以,如果是傳引用的方法調用,也同時可以了解為“傳引用值”的傳值調用,即引用的處理跟基本類型是完全一樣的。但是當進入被調用方法時,被傳遞的這個引用的值,被程式解釋(或者查找)到JVM堆中的對象,這個時候才對應到真正的對象。如果此時進行修改,修改的是引用對應的對象,而不是引用本身,即:修改的是JVM堆中的資料。是以這個修改是可以保持的了。
對象,從某種意義上說,是由基本類型組成的。可以把一個對象看作為一棵樹,對象的屬性如果還是對象,則還是一顆樹(即非葉子節點),基本類型則為樹的葉子節點。程式參數傳遞時,被傳遞的值本身都是不能進行修改的,但是,如果這個值是一個非葉子節點(即一個對象引用),則可以修改這個節點下面的所有内容。
JVM堆和JVM棧中,JVM棧是程式運作最根本的東西。程式運作可以沒有JVM堆,但是不能沒有JVM棧。而JVM堆是為JVM棧進行資料存儲服務,說白了JVM堆就是一塊共享的記憶體。不過,正是因為JVM堆和JVM棧的分離的思想,才使得Java的垃圾回收成為可能。