你就簡(jiǎn)單的來(lái)理解就可以了 堆棧就是兩種存放數(shù)據(jù)的方式
不要new直接來(lái)定義的是棧 用new來(lái)定義的就是堆
首先來(lái)講解棧 棧的優(yōu)勢(shì)是,存取速度比堆要快。但缺點(diǎn)是缺乏靈活性
而堆測(cè)試速度慢 但是靈活性好
比如八大基本數(shù)據(jù)類型 在你int sum = 0;的時(shí)候 就是sum是一個(gè)指向int類型的引用,指向0這個(gè)字面值
你在頂一個(gè) int i=0;他會(huì)去找有沒(méi)有0 有的話就會(huì)指向它 所以棧具有共享數(shù)據(jù)的特性
而當(dāng)你String str = new String("a");的時(shí)候 它就會(huì)在堆中建立一個(gè)對(duì)象
其實(shí)你就理解成兩種方式的存放數(shù)據(jù)的方式就行
簡(jiǎn)單的說(shuō) 其實(shí) 棧 就是存放變量引用的一個(gè)地方, 堆 就是存放實(shí)際對(duì)象的地方 也就是.
比如: int i = 7; 這個(gè) 其實(shí)是存在棧里邊的。內(nèi)容為 i = 7。
Apple app = new Apple(); 這個(gè) app 是在棧里邊的 他對(duì)應(yīng)的是一個(gè)內(nèi)存地址也在堆里邊, 而這個(gè)內(nèi)存地址對(duì)應(yīng)的是堆里邊存放 Apple 實(shí)例的地址。
String s = "Hello World!"; 這個(gè)其實(shí)是存在另外一塊靜態(tài)代碼區(qū)。
總體來(lái)說(shuō): 棧--主要存放引用 和基本數(shù)據(jù)類型。
堆--用來(lái)存放 new 出來(lái)的對(duì)象實(shí)例。
Java中堆棧的概念是邏輯上的,在完全符合Java規(guī)范的Java處理器面世之前,所有Java虛擬機(jī)提供的內(nèi)容都是由軟件模擬出來(lái)的。
什么叫堆?你用十幾個(gè)麻將牌豎直疊成一摞這叫堆,你可以從上面、下面、中間任意抽出一張牌,也可以任意插入一張。
什么叫棧?AK-47的彈匣就是一個(gè)棧,在上面的子彈沒(méi)被取出之前,你無(wú)法取出下面的子彈——盡管你可以從邊上的透明部分讀出里面裝的是什么型號(hào)、顏色的子彈。
堆很靈活,但是不安全。對(duì)于對(duì)象,我們要?jiǎng)討B(tài)地創(chuàng)建、銷毀,不能說(shuō)后創(chuàng)建的對(duì)象沒(méi)有銷毀,先前創(chuàng)建的對(duì)象就不能銷毀,那樣的話我們的程序就寸步難行,所以Java中用堆來(lái)存儲(chǔ)對(duì)象。而一旦堆中的對(duì)象被銷毀,我們繼續(xù)引用這個(gè)對(duì)象的話,就會(huì)出現(xiàn)著名的 NullPointerException,這就是堆的缺點(diǎn)——錯(cuò)誤的引用邏輯只有在運(yùn)行時(shí)才會(huì)被發(fā)現(xiàn)。
棧不靈活,但是很嚴(yán)格,是安全的,易于管理。因?yàn)橹灰厦娴囊脹](méi)有銷毀,下面引用就一定還在,所以,在棧中,上面引用永遠(yuǎn)可以通過(guò)下面引用來(lái)查找對(duì)象,同時(shí)如果確認(rèn)某一區(qū)間的內(nèi)容會(huì)一起存在、一起銷毀,也可以上下互相引用。在大部分程序中,都是先定義的變量、引用先進(jìn)棧,后定義的后進(jìn)棧,同時(shí),區(qū)塊內(nèi)部的變量、引用在進(jìn)入?yún)^(qū)塊時(shí)壓棧,區(qū)塊結(jié)束時(shí)出棧,理解了這種機(jī)制,我們就可以很方便地理解各種編程語(yǔ)言的作用域的概念了,同時(shí)這也是棧的優(yōu)點(diǎn)——錯(cuò)誤的引用邏輯在編譯時(shí)就可以被發(fā)現(xiàn)。
在Java中,引用可以理解為一個(gè)永遠(yuǎn)指向?qū)ο蟮闹羔槪琂ava沒(méi)有指向指針的指針。
關(guān)于堆棧的資料幾乎每個(gè)講數(shù)據(jù)結(jié)構(gòu)的書上都有,而至于Java中堆、棧的具體機(jī)制你可以參考一些關(guān)于Java虛擬機(jī)原理的書,不過(guò)這個(gè)好像比較難理解,我是沒(méi)指望理解的了。
以上都是我的個(gè)人觀點(diǎn),僅供參考。
內(nèi)存中的兩種存儲(chǔ)區(qū)
1..棧的特點(diǎn)是 容量小 速度快 適合存放小型數(shù)據(jù) 如基本數(shù)據(jù)類型和對(duì)象類型的引用
在棧中變量直接指向存放變量值的空間 對(duì)于對(duì)象引用則存放對(duì)象在堆中的內(nèi)存地址
2..堆的特點(diǎn)和棧相反 因此適合存放對(duì)象本身
3..對(duì)象引用訪問(wèn)對(duì)象的原理是 先通過(guò)該引用找到棧中的數(shù)據(jù) 即對(duì)象的地址 在通過(guò)該
地址訪問(wèn)對(duì)象 這就是為什么 對(duì)象 a=null; 調(diào)用a.方法(屬性) 會(huì)引發(fā)異常 因?yàn)檎也坏?/p>
實(shí)際對(duì)象的地址 向一個(gè)不存在的對(duì)象發(fā)送消息 如同叫一個(gè)不存在的人去幫你做事
程序不崩潰才怪
簡(jiǎn)單的說(shuō):Java把內(nèi)存劃分成兩種:一種是棧內(nèi)存,一種是堆內(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)存用來(lái)存放由new創(chuàng)建的對(duì)象和數(shù)組。在堆中分配的內(nèi)存,由Java虛擬機(jī)的自動(dòng)垃圾回收器來(lái)管理。在堆中產(chǎn)生了一個(gè)數(shù)組或?qū)ο蠛?,還可以在棧中定義一個(gè)特殊的變量,讓棧中這個(gè)變量的取值等于數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址,棧中的這個(gè)變量就成了數(shù)組或?qū)ο蟮囊米兞?。引用變量就相?dāng)于是為數(shù)組或?qū)ο笃鸬囊粋€(gè)名稱,以后就可以在程序中使用棧中的引用變量來(lái)訪問(wèn)堆中的數(shù)組或?qū)ο?/p>
堆棧是一種執(zhí)行“后進(jìn)先出”算法的數(shù)據(jù)結(jié)構(gòu)。
設(shè)想有一個(gè)直徑不大、一端開口一端封閉的竹筒。有若干個(gè)寫有編號(hào)的小球,小球的直徑比竹筒的直徑略小?,F(xiàn)在把不同編號(hào)的小球放到竹筒里面,可以發(fā)現(xiàn)一種規(guī)律:先放進(jìn)去的小球只能后拿出來(lái),反之,后放進(jìn)去的小球能夠先拿出來(lái)。所以“先進(jìn)后出”就是這種結(jié)構(gòu)的特點(diǎn)。
堆棧就是這樣一種數(shù)據(jù)結(jié)構(gòu)。它是在內(nèi)存中開辟一個(gè)存儲(chǔ)區(qū)域,數(shù)據(jù)一個(gè)一個(gè)順序地存入(也就是“壓入——push”)這個(gè)區(qū)域之中。有一個(gè)地址指針總指向最后一個(gè)壓入堆棧的數(shù)據(jù)所在的數(shù)據(jù)單元,存放這個(gè)地址指針的寄存器就叫做堆棧指示器。開始放入數(shù)據(jù)的單元叫做“棧底”。數(shù)據(jù)一個(gè)一個(gè)地存入,這個(gè)過(guò)程叫做“壓棧”。在壓棧的過(guò)程中,每有一個(gè)數(shù)據(jù)壓入堆棧,就放在和前一個(gè)單元相連的后面一個(gè)單元中,堆棧指示器中的地址自動(dòng)加1。讀取這些數(shù)據(jù)時(shí),按照堆棧指示器中的地址讀取數(shù)據(jù),堆棧指示器中的地址數(shù)自動(dòng)減 1。這個(gè)過(guò)程叫做“彈出pop”。如此就實(shí)現(xiàn)了后進(jìn)先出的原則。
堆棧是計(jì)算機(jī)中最常用的一種數(shù)據(jù)結(jié)構(gòu),比如函數(shù)的調(diào)用在計(jì)算機(jī)中是用堆棧實(shí)現(xiàn)的。
堆??梢杂脭?shù)組存儲(chǔ),也可以用以后會(huì)介紹的鏈表存儲(chǔ)。
下面是一個(gè)堆棧的結(jié)構(gòu)體定義,包括一個(gè)棧頂指針,一個(gè)數(shù)據(jù)項(xiàng)數(shù)組。棧頂指針最開始指向-1,然后存入數(shù)據(jù)時(shí),棧頂指針加1,取出數(shù)據(jù)后,棧頂指針減1。
#define MAX_SIZE 100
typedef int DATA_TYPE;
struct stack
{
DATA_TYPE data[MAX_SIZE];
int top;
};
在C++中,內(nèi)存分成5個(gè)區(qū),他們分別是堆、棧、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)。
棧,就是那些由編譯器在需要的時(shí)候分配,在不需要的時(shí)候自動(dòng)清楚的變量的存儲(chǔ)區(qū)。里面的變量通常是局部變量、函數(shù)參數(shù)等。
堆,就是那些由new分配的內(nèi)存塊,他們的釋放編譯器不去管,由我們的應(yīng)用程序去控制,一般一個(gè)new就要對(duì)應(yīng)一個(gè)delete。如果程序員沒(méi)有釋放掉,那么在程序結(jié)束后,操作系統(tǒng)會(huì)自動(dòng)回收。
自由存儲(chǔ)區(qū),就是那些由malloc等分配的內(nèi)存塊,他和堆是十分相似的,不過(guò)它是用free來(lái)結(jié)束自己的生命的。
全局/靜態(tài)存儲(chǔ)區(qū),全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的C語(yǔ)言中,全局變量又分為初始化的和未初始化的,在C++里面沒(méi)有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。
常量存儲(chǔ)區(qū),這是一塊比較特殊的存儲(chǔ)區(qū),他們里面存放的是常量,不允許修改(當(dāng)然,你要通過(guò)非正當(dāng)手段也可以修改,而且方法很多.
聲明:本網(wǎng)站尊重并保護(hù)知識(shí)產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護(hù)條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請(qǐng)?jiān)谝粋€(gè)月內(nèi)通知我們,我們會(huì)及時(shí)刪除。
蜀ICP備2020033479號(hào)-4 Copyright ? 2016 學(xué)習(xí)鳥. 頁(yè)面生成時(shí)間:2.943秒