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