1. 棧:實(shí)際上就是滿足后進(jìn)先出的性質(zhì),是一種數(shù)據(jù)項(xiàng)按序排列的數(shù)據(jù)結(jié)構(gòu),只能在一端(稱為棧頂(top))對(duì)數(shù)據(jù)項(xiàng)進(jìn)行插入和刪除。

2. 堆:堆是一種完全二叉樹或者近似完全二叉樹,完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),像十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能優(yōu)化。

堆排序(Heapsort)是指利用堆這種數(shù)據(jù)結(jié)構(gòu)所設(shè)計(jì)的一種排序算法。詳見:十大經(jīng)典排序算法

系統(tǒng)方面的堆和棧
1、棧區(qū)(stack)— 由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
2、堆區(qū)(heap)— 是一個(gè)可動(dòng)態(tài)申請(qǐng)的內(nèi)存空間(其記錄空閑內(nèi)存空間的鏈表由操作系統(tǒng)維護(hù)),在java中,所有使用new xxx()構(gòu)造出來(lái)的對(duì)象都在堆中存儲(chǔ)一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表。
堆是全局的,堆棧是每個(gè)函數(shù)進(jìn)入的時(shí)候分一小塊,函數(shù)返回的時(shí)候就釋放了,靜態(tài)和全局變量,new得到的變量,都放在堆中,局部變量放在棧中,所以函數(shù)返回,局部變量就全沒了。
我們今天重點(diǎn)講的是Java里的堆和棧也就是系統(tǒng)方面的堆和棧。
Java里的堆、棧和常量池
(下面以圖文的方式講解,方便大家理解)
1. 棧(stack)與堆(heap)都是Java用來(lái)在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動(dòng)管理?xiàng):投?,程序員不能直接地設(shè)置?;蚨?。
2. 棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。另外,棧數(shù)據(jù)可以共享,詳見第3點(diǎn)。
堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,所有使用new xxx()構(gòu)造出來(lái)的對(duì)象都在堆中存儲(chǔ),生存期也不必事先告訴編譯器,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。
3. 常量池:存放字符串常量和基本類型常量(public static final)。
常量池的好處是為了避免頻繁的創(chuàng)建和銷毀對(duì)象而影響系統(tǒng)性能,其實(shí)現(xiàn)了對(duì)象的共享。
例如字符串常量池,在編譯階段就把所有的字符串文字放到一個(gè)常量池中。
(1)節(jié)省內(nèi)存空間:常量池中所有相同的字符串常量被合并,只占用一個(gè)空間。
(2)節(jié)省運(yùn)行時(shí)間:比較字符串時(shí),==比equals()快。對(duì)于兩個(gè)引用變量,只用==判斷引用是否相等,也就可以判斷實(shí)際值是否相等。
4. Java中的數(shù)據(jù)類型有兩種。
一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,不包含String)。
如int a = 3; 這里的a是一個(gè)指向int類型的引用,指向3這個(gè)字面值。這些字面值的數(shù)據(jù),由于大小可知,生存期可知(這些字面值固定定義在某個(gè)程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧中。