Content Introduce
Java程序都運(yùn)行在JVM虛擬機(jī)內(nèi)部
| JVM內(nèi)存 | 內(nèi)存占用 | 釋放 | 優(yōu)點(diǎn) | 缺點(diǎn) | 共享 | 超出 |
|---|---|---|---|---|---|---|
| 堆區(qū)(heap) | new創(chuàng)建的對(duì)象 | 虛擬機(jī)GC | 靈活 | 效率低 | 全局共享 | OOM |
| 棧區(qū)(stack) | 存儲(chǔ)局部變量,引用變量 | 自動(dòng)釋放 | 效率高 | 內(nèi)存有限(遞歸小心) | 單獨(dú)線程共享 | SOF |
| 靜態(tài)區(qū)(static) | 全局 static 數(shù)據(jù),常量 | 整個(gè)運(yùn)行期間 | 共享給所有 | 加大內(nèi)存負(fù)擔(dān) | 全局共享 |
由于mk的語(yǔ)法原因上面不能寫全,更加詳細(xì)的,見(jiàn)下圖

其中靜態(tài)區(qū)其實(shí)叫方法區(qū),又叫no-heap 非堆區(qū),它與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等。
數(shù)據(jù)。
sample
public class Sample() {
int s1 = 0;
Sample mSample1 = new Sample();
public void method() {
int s2 = 1;
Sample mSample2 = new Sample();
}
}
Sample mSample3 = new Sample();
說(shuō)明:
Sample 類的局部變量 s2 和引用變量 mSample2 都是存在于棧中,但 mSample2 指向的對(duì)象是存在于堆上的。
mSample3 指向的對(duì)象實(shí)體存放在堆上,包括這個(gè)對(duì)象的所有成員變量 s1 和 mSample1,而它自己存在于棧中。
Detailed description
棧內(nèi)存, 在函數(shù)中定義的一些基本類型的變量和對(duì)象的引用變量都是在函數(shù)的棧內(nèi)存中分配。當(dāng)在一段代碼塊中定義一個(gè)變量時(shí),java就在棧中為這個(gè)變量分配內(nèi)存空間,當(dāng)超過(guò)變量的作用域后,java會(huì)自動(dòng)釋放掉為該變量分配的內(nèi)存空間,該內(nèi)存空間可以立刻被另作他用。
堆內(nèi)存用于存放由new創(chuàng)建的對(duì)象和數(shù)組。在堆中分配的內(nèi)存,由java虛擬機(jī)自動(dòng)垃圾回收器來(lái)管理。在堆中產(chǎn)生了一個(gè)數(shù)組或者對(duì)象后,還可以在棧中定義一個(gè)特殊的變量,這個(gè)變量的取值等于數(shù)組或者對(duì)象在堆內(nèi)存中的首地址,在棧中的這個(gè)特殊的變量就變成了數(shù)組或者對(duì)象的引用變量,以后就可以在程序中使用棧內(nèi)存中的引用變量來(lái)訪問(wèn)堆中的數(shù)組或者對(duì)象,引用變量相當(dāng)于為數(shù)組或者對(duì)象起的一個(gè)別名,或者代號(hào)。
引用變量是普通變量,定義時(shí)在棧中分配內(nèi)存,引用變量在程序運(yùn)行到作用域外釋放。而數(shù)組&對(duì)象本身在堆中分配,即使程序運(yùn)行到使用new產(chǎn)生數(shù)組和對(duì)象的語(yǔ)句所在地代碼塊之外,數(shù)組和對(duì)象本身占用的堆內(nèi)存也不會(huì)被釋放,數(shù)組和對(duì)象在沒(méi)有引用變量指向它的時(shí)候,才變成垃圾,不能再被使用,但是仍然占著內(nèi)存,在隨后的一個(gè)不確定的時(shí)間被垃圾回收器釋放掉。這個(gè)也是java比較占內(nèi)存的主要原因,********實(shí)際上,棧中的變量指向堆內(nèi)存中的變量,這就是 Java 中的指針!
參考:
http://blog.csdn.net/codeemperor/article/details/51514448
http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html