堆和棧

一 java 堆內(nèi)存和棧內(nèi)存

java把內(nèi)存分為兩種:一種是堆內(nèi)存,一種是棧內(nèi)存

堆: 堆內(nèi)存主要存儲(chǔ)實(shí)例化對(duì)象,數(shù)組挨措。由JVM動(dòng)態(tài)分配內(nèi)存空間。一個(gè)JVM只有一個(gè)堆內(nèi)存崩溪,線程是可以共享數(shù)據(jù)的。

棧:主要存儲(chǔ)局部變量和對(duì)象的引用變量斩松。每個(gè)線程都會(huì)有一個(gè)獨(dú)立的空間伶唯,所以線程之間的數(shù)據(jù)是不可以共享的。

在函數(shù)中定義的一些基本數(shù)據(jù)變量和對(duì)象的引用變量都會(huì)存儲(chǔ)到棧內(nèi)存中惧盹,當(dāng)在一段代碼中定義一段變量時(shí)乳幸,java就在棧內(nèi)存中為這個(gè)變量分配內(nèi)存空間,當(dāng)超過(guò)這個(gè)變量的作用域后钧椰,java會(huì)自動(dòng)釋放掉該變量分配的內(nèi)存空間粹断,該內(nèi)存的空間可以立即被另做它用。

堆內(nèi)存用于存放新建new對(duì)象和數(shù)組嫡霞。

在堆中分配內(nèi)存瓶埋,由java虛擬機(jī)自動(dòng)垃圾回收來(lái)處理。

二、堆和棧的共同點(diǎn)和優(yōu)缺點(diǎn)

1养筒、棧(stack)與堆(heap)都是java用于在Raw存放數(shù)據(jù)的地方曾撤,與C++不同,java自動(dòng)關(guān)了堆和棧晕粪,程序員不能設(shè)置堆和棧挤悉。

2、棧的優(yōu)勢(shì)是巫湘,存儲(chǔ)數(shù)據(jù)快装悲,僅次于cup中的寄存器,但缺點(diǎn)是尚氛,存在存在棧中的數(shù)據(jù)大小與生存期必須是確定的诀诊,缺乏靈活性,另外怠褐,棧內(nèi)存數(shù)據(jù)可以共享(這可能跟上面說(shuō)的有點(diǎn)沖突畏梆,上面剛說(shuō)的數(shù)據(jù)不能共享,現(xiàn)在又說(shuō)可以共享奈懒,很矛盾奠涌,但是,棧內(nèi)存在同一個(gè)線程中的數(shù)據(jù)是可以共享的磷杏,其他線程是不共享的)溜畅,堆內(nèi)存的優(yōu)勢(shì)是可以動(dòng)態(tài)的分配內(nèi)存的大小,生存期也不必要事先告訴編譯器极祸,java垃圾回收機(jī)制會(huì)自動(dòng)收走這些不在使用的數(shù)據(jù)慈格,但缺點(diǎn)是,由于運(yùn)行時(shí)是動(dòng)態(tài)分配內(nèi)存的遥金,所以存取速度較慢浴捆。

3、java中的數(shù)據(jù)類(lèi)型有兩種

一種是基本數(shù)據(jù)類(lèi)型(primitive types)稿械,共有8種选泻,即 int,short,long,byte,float,double,boolean, char(童鞋們要注意了,這里string不是基本類(lèi)型)這種類(lèi)型的定義是通過(guò)諸如 int a=3; long b =255L; 的形式來(lái)定義的美莫,稱為自動(dòng)變量页眯,值得注意的是,自動(dòng)變量存的是字面值厢呵,不是類(lèi)的實(shí)列窝撵,即不是類(lèi)的引用,這里并沒(méi)有類(lèi)的存在襟铭,如 int a = 3 碌奉;這里的a是一個(gè)指向int類(lèi)的引用短曾,指向3的字面值,這些字面值的數(shù)據(jù)道批,大小可知错英,生存期可知(這些字面值固定定義在某個(gè)程序模塊里面,程序塊退化后隆豹,字段值就消失了)椭岩,出于追求速度的就存在棧內(nèi)存中。

棧有個(gè)特殊的重要性璃赡,就是存在棧中的數(shù)據(jù)可以共享判哥。

假設(shè)我們同時(shí)定義

int a = 3; int b = 3;

編譯器先處理 int a =? 3;首先他會(huì)在棧中創(chuàng)建一個(gè)變量值為a的引用,然后在查找有沒(méi)有字面值為3的地址碉考,沒(méi)找到塌计,就開(kāi)辟一個(gè)存放3的字面值地址,然后將a指向3的地址侯谁,接著處理 int b = 3锌仅;在創(chuàng)建完b的引用變量后,由于在棧中已有有了3 的字面值墙贱,便將b直接指向3的地址热芹,這樣a和b同時(shí)指向了3的情況。

特別注意的是惨撇,這種字面值的引用與類(lèi)對(duì)象的引用不同伊脓,假設(shè)兩個(gè)對(duì)象的引用同時(shí)指向一個(gè)對(duì)象,如果一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)象的內(nèi)部狀態(tài)魁衙,那么另一個(gè)對(duì)象引用變量也會(huì)立刻反應(yīng)出這個(gè)變化报腔。相反,通過(guò)字面值的引用來(lái)修改其值剖淀,不會(huì)導(dǎo)致另外一個(gè)指向此字面值的引用的值也跟著改變的情況纯蛾。這就是上述情況,如果a的字面值更改成4后纵隔,b的字面值依然是3 茅撞,不會(huì)因?yàn)閍的字面值改變而改變。

另一種是包裝類(lèi)數(shù)據(jù)巨朦。如 Integer,String ,Double等將相應(yīng)的基本數(shù)據(jù)類(lèi)型包裝起來(lái)的類(lèi)。這些數(shù)據(jù)類(lèi)型全部存儲(chǔ)在堆內(nèi)存中剑令,java 用 new()語(yǔ)句來(lái)顯示的告訴編譯器糊啡,在運(yùn)行是才根據(jù)需要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活吁津,缺點(diǎn)是占用更多的時(shí)間

三棚蓄、堆和棧的區(qū)別

1堕扶、各司其職

最主要的區(qū)別就是棧內(nèi)存用于存儲(chǔ)局部變量和方法的調(diào)用。而堆內(nèi)存用來(lái)存儲(chǔ)java中的對(duì)象梭依,無(wú)論是成員變量稍算,局部變量還是類(lèi)變量,他們指向的對(duì)象都存儲(chǔ)在堆內(nèi)存中役拴。

2糊探、獨(dú)有還是共享

棧內(nèi)存歸屬于單個(gè)線程,每個(gè)線程都會(huì)有一個(gè)棧內(nèi)存河闰,其存儲(chǔ)變量只能在所屬線程中可見(jiàn)科平、共享,即棧內(nèi)存可以理解為線程的私有內(nèi)存姜性。而堆內(nèi)存中的對(duì)象對(duì)所有線程可見(jiàn)瞪慧。堆內(nèi)存中的對(duì)象可以被所有線程訪問(wèn)。

3部念、異常錯(cuò)誤

如果棧內(nèi)存沒(méi)有可用空間存儲(chǔ)方法調(diào)用和局部變量弃酌,JVM會(huì)拋出Java.lang.StackOverFlowError

如果堆內(nèi)存沒(méi)有可用空間存儲(chǔ)生成的對(duì)象,JVM會(huì)拋出Java.lang.OutOfMemoryError.

4儡炼、空間大小

棧的內(nèi)存要原因小于堆內(nèi)存妓湘,如果你使用遞歸的話,那你的棧內(nèi)存會(huì)很快充滿射赛,如果遞歸沒(méi)有及時(shí)跳出多柑,很可能會(huì)發(fā)送StackOverFlowError問(wèn)題。

你可以通過(guò)-Xss選項(xiàng)設(shè)置棧內(nèi)存的大小楣责。-Xss選項(xiàng)可以設(shè)置堆開(kāi)始時(shí)的大小竣灌,-Xmx選項(xiàng)可以設(shè)置堆內(nèi)存的最大值。

這就是java中的堆和棧秆麸,理解好這個(gè)問(wèn)題初嘹,可以對(duì)你解決開(kāi)發(fā)中的問(wèn)題,分析堆和棧內(nèi)存使用沮趣,甚至性能調(diào)優(yōu)都有幫助屯烦。

四、java中的堆和棧

JVM是基于堆棧的虛擬機(jī)房铭,JVM為每個(gè)新創(chuàng)建的線程都分配了一個(gè)堆棧驻龟,也就是說(shuō),對(duì)于一個(gè)java程序員來(lái)說(shuō)缸匪。他的運(yùn)行就是通過(guò)對(duì)堆棧的操作來(lái)完成的翁狐。堆棧以幀為單位保持線程的狀態(tài),JVM對(duì)堆棧只進(jìn)行兩鐘操作:以幀為單位的壓棧和出棧操作凌蔬,我們知道露懒,某個(gè)線程正在執(zhí)行的方法稱為次線程的當(dāng)前方法闯冷,我們可能不知道,當(dāng)前方法使用的幀稱為當(dāng)前幀懈词。當(dāng)線程激活一個(gè)java方法蛇耀,JVM就會(huì)在java的堆棧中新壓入一個(gè)幀。這個(gè)幀自然稱為了當(dāng)前幀坎弯,在此方法執(zhí)行期間纺涤,這個(gè)幀將用來(lái)保存參數(shù),局部變量荞怒,中間計(jì)算過(guò)程和其他數(shù)據(jù)洒琢。這個(gè)這在這里和編譯原理中的活動(dòng)記錄的概念差不多的,從java的這種分配機(jī)制來(lái)看褐桌,堆棧又可以這樣理解衰抑,堆棧(stack)是操作系統(tǒng)在建立某個(gè)進(jìn)程時(shí)或者線程(在支持多線程操作系統(tǒng)中的線程)為這個(gè)線程建立的存儲(chǔ)區(qū)域。該區(qū)域具有先進(jìn)后出的特性荧嵌。

每一個(gè)java應(yīng)用都唯一對(duì)應(yīng)一個(gè)JVM實(shí)例呛踊,每一個(gè)實(shí)例唯一對(duì)應(yīng)一個(gè)堆。應(yīng)用程序在運(yùn)行中所創(chuàng)建的所有類(lèi)實(shí)例或數(shù)組都放在這個(gè)堆中啦撮,并由應(yīng)用所有的線程共享谭网,跟C/C++不同,java分配堆內(nèi)存是自動(dòng)初始化的赃春,Java中所有對(duì)象的 存儲(chǔ)空間都是在堆中分配的愉择,也就是說(shuō)在建立一個(gè)對(duì)象時(shí),在兩個(gè)地方都分配內(nèi)存织中,在堆中分配的內(nèi)存實(shí)際建立這個(gè)對(duì)象锥涕,而在堆中分配的內(nèi)存只有一個(gè)指向這個(gè)堆對(duì)象的指針(引用)而已。

Java把內(nèi)存劃分成兩種:一種是棧內(nèi)存狭吼,另一種是堆內(nèi)存层坠。在函數(shù)中定義的一些基本類(lèi)型的變量和對(duì)象的引用變量都在函數(shù)的棧內(nèi)存中分配,當(dāng)在一段代碼定義一個(gè)變量時(shí)刁笙,Java就在棧中為這個(gè)變量分配內(nèi)存空間破花,當(dāng)超過(guò)變量的作用域后,Java自動(dòng)釋放掉為該變量分配的內(nèi)存空間疲吸,該內(nèi)存空間可以立即另作它用座每。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市摘悴,隨后出現(xiàn)的幾起案子尺栖,更是在濱河造成了極大的恐慌,老刑警劉巖烦租,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件延赌,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡叉橱,警方通過(guò)查閱死者的電腦和手機(jī)挫以,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)窃祝,“玉大人掐松,你說(shuō)我怎么就攤上這事》嘈。” “怎么了大磺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)探膊。 經(jīng)常有香客問(wèn)我杠愧,道長(zhǎng),這世上最難降的妖魔是什么逞壁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任流济,我火速辦了婚禮,結(jié)果婚禮上腌闯,老公的妹妹穿的比我還像新娘绳瘟。我一直安慰自己,他們只是感情好姿骏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布糖声。 她就那樣靜靜地躺著,像睡著了一般分瘦。 火紅的嫁衣襯著肌膚如雪蘸泻。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天擅腰,我揣著相機(jī)與錄音蟋恬,去河邊找鬼。 笑死趁冈,一個(gè)胖子當(dāng)著我的面吹牛歼争,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渗勘,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼沐绒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了旺坠?” 一聲冷哼從身側(cè)響起乔遮,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎取刃,沒(méi)想到半個(gè)月后蹋肮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體出刷,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年坯辩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馁龟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡漆魔,死狀恐怖坷檩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情改抡,我是刑警寧澤矢炼,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站阿纤,受9級(jí)特大地震影響句灌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜阵赠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一涯塔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧清蚀,春花似錦匕荸、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至东揣,卻和暖如春践惑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嘶卧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工尔觉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芥吟。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓侦铜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親钟鸵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子钉稍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 在函數(shù)中定義的一些基本類(lèi)型的變量和對(duì)象的引用變量都在函數(shù)的棧內(nèi)存中分配。 當(dāng)在一段代碼塊定義一個(gè)變量時(shí)棺耍,Java就...
    木有魚(yú)丸啦閱讀 553評(píng)論 0 0
  • 引言:看了網(wǎng)上一些作品贡未,沒(méi)有特別清晰的一個(gè)結(jié)構(gòu),所以,這里本人整理一下Java的堆棧相關(guān)知識(shí)俊卤。Java 中的堆和棧...
    androidjp閱讀 13,394評(píng)論 18 189
  • 01 我開(kāi)始注意小A是在大二的時(shí)候嫩挤。在那時(shí)我是班委,班里突然通知要采集指紋信息瘾蛋,班里的人全都到了俐镐,除了小A。 我就...
    蘇固閱讀 829評(píng)論 2 6
  • 姬川明(組合)算是賽爾達(dá)漫畫(huà)的專(zhuān)業(yè)戶了哺哼。我記得我小學(xué)三年級(jí)的時(shí)候就在看他們畫(huà)的塞爾達(dá)了。當(dāng)時(shí)剛剛通關(guān)縮小帽叼风,然后在...
    伊蒂雅閱讀 1,541評(píng)論 0 2
  • 早上起來(lái)取董,心情是特別的差。而罪魁禍?zhǔn)拙褪怯⒄Z(yǔ)書(shū)无宿、小本子和英語(yǔ)練習(xí)冊(cè)的離奇失蹤茵汰。沒(méi)了他們,別說(shuō)英語(yǔ)作業(yè)了孽鸡,其他作...
    故夢(mèng)_9dc8閱讀 127評(píng)論 0 0