java內(nèi)存分配分析/棧內(nèi)存、堆內(nèi)存

首先學(xué)習(xí)JVM相關(guān)需要需要內(nèi)存的組成讹剔。

基本內(nèi)容


  • java動態(tài)創(chuàng)建對象,即對于new的一個實(shí)例對象详民。但是需要注意的是該實(shí)例對象的成員變量都存儲在各自的堆區(qū)域中延欠,其中對象方法是在堆中共享,即不是每次創(chuàng)建都復(fù)制一份沈跨。

  • 保存局部變量的值包括
    1. 基本數(shù)據(jù)變量
    2. 引用變量的保存由捎,即堆對象的引用。當(dāng)然也可以用來保存加載方法時的幀饿凛。
  • 寄存器
    JVM內(nèi)部虛擬寄存器狞玛,存取速度非沉诘欤快,程序不可控制为居。
  • 常量池
    • 首先明確的是:常量池存在于堆中。
    • 即JVM為每個已加載的類型開辟一塊區(qū)域杀狡,包括基本類型和String類型(其中Float和Double除外)蒙畴,對其他類型、方法呜象、字段的符號引用膳凝。
    • 池中的數(shù)據(jù)和數(shù)組一樣通過索引訪問
    • 由于常量池包含了一個類型所有的對其他類型恭陡、方法蹬音、字段的符號引用,所以常量池在Java的動態(tài)鏈接中起了核心作用休玩。
  • 代碼區(qū)
    用來存放從硬盤上讀取的源程序代碼著淆。
  • 數(shù)據(jù)段
    用來存放static修飾的靜態(tài)成員(在java中static的作用就是說明該變量,方法拴疤,代碼塊是屬于類的還是屬于實(shí)例的

示意圖展示

內(nèi)存組成.jpg

)永部。

個人經(jīng)驗(yàn)之談


總結(jié):

  1. 分清什么是對象引用變量(引用變量)什么是對象。Class a= new Class();此時a叫對象引用變量呐矾,而不能說a是對象苔埋。引用變量在棧中,對象在堆中蜒犯,操作引用變量實(shí)際上是通過引用間接操作對象组橄。多個引用變量可以引用到同一個對象。
  2. 棧中的數(shù)據(jù)和堆中的數(shù)據(jù)銷毀并不是同步的罚随。方法一旦結(jié)束玉工,棧中的局部變量立即銷毀,但是堆中對象不一定銷毀毫炉。因?yàn)榭赡苡衅渌兞恳仓赶蛄诉@個對象瓮栗,直到棧中沒有變量指向堆中的對象時,它才銷毀瞄勾,而且還不是馬上銷毀费奸,要等垃圾回收掃描時才可以被銷毀。****
  3. 每個方法執(zhí)行的時候都會建立自己的棧區(qū)进陡,在方法中定義的局部變量(參數(shù)愿阐,方法中定義的變量)都在棧區(qū)中存放當(dāng)方法結(jié)束時這些局部變量也就結(jié)束了,但是堆內(nèi)存中的對象不會隨著方法的結(jié)束而銷毀而是判斷還有沒有引用變量引用到這個對象如果有的話就是說這個對象可達(dá)所以不會輕易的被GC回收趾疚,如果這個對象沒有被引用如果這時垃圾回收系統(tǒng)開始回收但發(fā)現(xiàn)這個對象沒有引用的話就會調(diào)用finalize()方法來判斷這個對象是否可以再次可達(dá)如果可以的不會回收但是不過不可達(dá)的話可能會被回收(不是一定會被回收這里是不一定會回收因?yàn)檫@里還有對象的引用類型如:強(qiáng)引用缨历,軟引用(softReference來實(shí)現(xiàn))以蕴,弱引用(WeakReference來實(shí)現(xiàn))等因素有關(guān),還要考慮其他的因素不在這里一一說明)如果可達(dá)的話還是不會回收的辛孵。
  4. 以上的棧丛肮、堆、代碼段魄缚、數(shù)據(jù)段等等都是相對于應(yīng)用程序而言的宝与。每一個應(yīng)用程序都對應(yīng)唯一的一個JVM實(shí)例,每一個JVM實(shí)例都有自己的內(nèi)存區(qū)域冶匹,互不影響习劫,調(diào)用JVM也就是激活一個進(jìn)程。并且這些內(nèi)存區(qū)域是所有線程共享的嚼隘。這里提到的棧和堆都是整體上的概念诽里,這些堆棧還可以細(xì)分。
  5. 類中定義的實(shí)例成員變量在不同對象中各不相同飞蛹,都有自己的存儲空間(成員變量在堆中的對象中)谤狡。而類中定義的方法卻是該類的所有對象共享的,只有一套卧檐,對象使用方法的時候方法才被壓入棧豌汇,方法不使用則不占用內(nèi)存。

以上分析只涉及了棧和堆泄隔,還有一個非常重要的內(nèi)存區(qū)域:常量池拒贱,這個地方往往出現(xiàn)一些莫名其妙的問題。只要記住它維護(hù)了一個已加載類的常量就可以了佛嬉。接下來結(jié)合一些例子說明常量池的特性逻澳。

預(yù)備知識:


基本類型和基本類型的包裝類∨唬基本類型有:byte斜做、short、char湾揽、int瓤逼、long、boolean库物“云欤基本類型的包裝類分別是:Byte、Short戚揭、Character诱告、Integer、Long民晒、Boolean精居。注意區(qū)分大小寫锄禽。二者的區(qū)別是:基本類型體現(xiàn)在程序中是普通變量,基本類型的包裝類是類靴姿,體現(xiàn)在程序中是引用變量沃但。因此二者在內(nèi)存中的存儲位置不同:基本類型存儲在棧中,而基本類型包裝類存儲在堆中佛吓。上邊提到的這些包裝類都****實(shí)現(xiàn)了常量池技術(shù)绽慈,而兩種浮點(diǎn)數(shù)類型的包裝類則沒有實(shí)現(xiàn)。另外辈毯,String類型也實(shí)現(xiàn)了常量池技術(shù)。

實(shí)例:

public class test {  
    public static void main(String[] args) {      
        objPoolTest();  
    }  
    public static void objPoolTest() {  
        int i = 40;  
        int i0 = 40;  
        Integer i1 = 40;  
        Integer i2 = 40;  
        Integer i3 = 0;  
        Integer i4 = new Integer(40);  
        Integer i5 = new Integer(40);  
        Integer i6 = new Integer(0);  
        Double d1=1.0;  
        Double d2=1.0;  
          //在java中對于引用變量來說“==”就是判斷這兩個引用變量所引用的是不是同一個對象
        System.out.println("i==i0\t" + (i == i0));  
        System.out.println("i1==i2\t" + (i1 == i2));  
        System.out.println("i1==i2+i3\t" + (i1 == i2 + i3));  
        System.out.println("i4==i5\t" + (i4 == i5));  
        System.out.println("i4==i5+i6\t" + (i4 == i5 + i6));      
        System.out.println("d1==d2\t" + (d1==d2));   
        System.out.println();          
    }  
}  

結(jié)果:

i==i0    true  
i1==i2   true  
i1==i2+i3        true  
i4==i5   false  
i4==i5+i6        true  
d1==d2   false  

結(jié)果分析:


  1. i和i0均是普通類型(int)的變量搜贤,所以數(shù)據(jù)直接存儲在棧中谆沃,而棧有一個很重要的特性:棧中的數(shù)據(jù)可以共享。當(dāng)我們定義了int i = 40;仪芒,再定義int i0 = 40;這時候會自動檢查棧中是否有40這個數(shù)據(jù)唁影,如果有,i0會直接指向i的40掂名,不會再添加一個新的40据沈。
  2. i1和i2均是引用類型,在棧中存儲指針饺蔑,因?yàn)镮nteger是包裝類锌介。由于Integer包裝類實(shí)現(xiàn)了常量池技術(shù),因此i1猾警、i2的40均是從常量池中獲取的孔祸,均指向同一個地址,因此i1==12发皿。
  3. 很明顯這是一個加法運(yùn)算崔慧,Java的數(shù)學(xué)運(yùn)算都是在棧中進(jìn)行的Java會自動對i1穴墅、i2進(jìn)行拆箱操作轉(zhuǎn)化成整型惶室,因此i1在數(shù)值上等于i2+i3。
  4. i4和i5均是引用類型玄货,在棧中存儲指針皇钞,因?yàn)镮nteger是包裝類。但是由于他們各自都是new出來的松捉,因此不再從常量池尋找數(shù)據(jù)鹅士,而是從堆中各自new一個對象,然后各自保存指向?qū)ο蟮闹羔槼涂樱詉4和i5不相等掉盅,因?yàn)樗麄兯娴刂凡煌舶荩玫降膶ο蟛煌?/li>
  5. 這也是一個加法運(yùn)算,和3同理趾痘。
  6. d1和d2均是引用類型慢哈,在棧中存儲指針,因?yàn)镈ouble是包裝類永票。但Double包裝類沒有實(shí)現(xiàn)常量池技術(shù)卵贱,因此Doubled1=1.0;相當(dāng)于Double d1=new Double(1.0);,是從堆new一個對象侣集,d2同理键俱。因此d1和d2存放的指針不同,指向的對象不同世分,所以不相等编振。

小結(jié):


  1. 以上提到的幾種基本類型包裝類均實(shí)現(xiàn)了常量池技術(shù),但他們維護(hù)的常量僅僅是【-128至127】這個范圍內(nèi)的常量臭埋,如果常量值超過這個范圍踪央,就會從堆中創(chuàng)建對象,不再從常量池中取瓢阴。比如畅蹂,把上邊例子改成Integer i1 = 400; Integer i2 = 400;,很明顯超過了127荣恐,無法從常量池獲取常量液斜,就要從堆中new新的Integer對象,這時i1和i2就不相等了叠穆。
  2. String類型也實(shí)現(xiàn)了常量池技術(shù)旗唁,但是稍微有點(diǎn)不同。String型是先檢測常量池中有沒有對應(yīng)字符串痹束,如果有检疫,則取出來;如果沒有祷嘶,則把當(dāng)前的添加進(jìn)去屎媳。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市论巍,隨后出現(xiàn)的幾起案子烛谊,更是在濱河造成了極大的恐慌,老刑警劉巖嘉汰,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丹禀,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)双泪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門持搜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人焙矛,你說我怎么就攤上這事葫盼。” “怎么了村斟?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵贫导,是天一觀的道長。 經(jīng)常有香客問我蟆盹,道長孩灯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任逾滥,我火速辦了婚禮峰档,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匣距。我一直安慰自己,他們只是感情好哎壳,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布毅待。 她就那樣靜靜地躺著,像睡著了一般归榕。 火紅的嫁衣襯著肌膚如雪尸红。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天刹泄,我揣著相機(jī)與錄音外里,去河邊找鬼。 笑死特石,一個胖子當(dāng)著我的面吹牛盅蝗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姆蘸,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼墩莫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逞敷?” 一聲冷哼從身側(cè)響起狂秦,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎推捐,沒想到半個月后裂问,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年堪簿,在試婚紗的時候發(fā)現(xiàn)自己被綠了痊乾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡戴甩,死狀恐怖符喝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甜孤,我是刑警寧澤协饲,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站缴川,受9級特大地震影響茉稠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜把夸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一而线、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恋日,春花似錦膀篮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谈截,卻和暖如春筷屡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背簸喂。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工毙死, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喻鳄。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓扼倘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親除呵。 傳聞我的和親對象是個殘疾皇子唉锌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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

  • 本文將由淺入深詳細(xì)介紹Java內(nèi)存分配的原理,以幫助新手更輕松的學(xué)習(xí)Java竿奏。這類文章網(wǎng)上有很多袄简,但大多比較零碎。...
    OSET我要編程閱讀 877評論 0 1
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理泛啸,因此不免有一些不準(zhǔn)確的地方绿语,同時不同JDK版本的...
    高廣超閱讀 15,545評論 3 83
  • java筆記第一天 == 和 equals ==比較的比較的是兩個變量的值是否相等,對于引用型變量表示的是兩個變量...
    jmychou閱讀 1,485評論 0 3
  • 相關(guān)概念 常量池的定義常量池(constant pool):指的是在編譯期被確定,并被保存在已編譯的.class文...
    snoweek閱讀 785評論 0 4
  • 最近身邊
    依依妍閱讀 142評論 0 0