qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          Java內(nèi)存回收機(jī)制

          一、Java對(duì)象在內(nèi)存引用狀態(tài)
            內(nèi)存泄露:程序運(yùn)行過(guò)程中,會(huì)不斷分配內(nèi)存空間,那些不再使用的內(nèi)存空間應(yīng)該即時(shí)回收它們,從而保證系統(tǒng)可以再次使用這些內(nèi)存,如果存在無(wú)用的內(nèi)存沒(méi)有被回收回來(lái),這就是內(nèi)存泄漏.
            (1)強(qiáng)引用
            這是java程序中最常見(jiàn)的引用方式,程序創(chuàng)建一個(gè)對(duì)象,并把這個(gè)對(duì)象賦給一個(gè)引用變量,這個(gè)引用變量就是強(qiáng)引用.java程序可通過(guò)強(qiáng)引用來(lái)訪問(wèn)實(shí)際的對(duì)象。當(dāng)一個(gè)對(duì)象被一個(gè)或一個(gè)以上的強(qiáng)引用變量引用時(shí),它處于可達(dá)狀態(tài),它不可能被系統(tǒng)垃圾回收機(jī)制回收。
            強(qiáng)引用是Java編程中廣泛使用的引用類(lèi)型,被強(qiáng)引用所引用的Java對(duì)象絕不會(huì)被垃圾回收機(jī)制回收,即使系統(tǒng)內(nèi)存緊張;即使有些Java對(duì)象以后永遠(yuǎn)也不會(huì)被用到,JVM也不會(huì)回收被強(qiáng)引用所引用的Java對(duì)象.
            由于JVM肯定不會(huì)回收強(qiáng)引用所引用的JAVA對(duì)象,因此強(qiáng)引用是造成JAVA內(nèi)存泄漏的主要原因。
            如 ReceiptBean rb=new ReceiptBean(); rb就代表了一種強(qiáng)引用的方式
            (2)軟引用
            軟引用需要通過(guò)SoftReference類(lèi)來(lái)實(shí)現(xiàn),當(dāng)一個(gè)對(duì)象只具有軟引用時(shí),它可能被垃圾回收機(jī)制回收。對(duì)于只有軟引用的對(duì)象而言,當(dāng)系統(tǒng)內(nèi)存空間足夠時(shí),它不會(huì)被系統(tǒng)回收,程序也可以使用該對(duì)象;當(dāng)系統(tǒng)內(nèi)存空間不足時(shí),系統(tǒng)將回收它.
            軟引用通常用在對(duì)內(nèi)存敏感的程序中,軟引用是強(qiáng)引用很好的替代。對(duì)于軟引用,當(dāng)系統(tǒng)內(nèi)存空間充足時(shí),軟引用與強(qiáng)引用沒(méi)有太大的區(qū)別,當(dāng)系統(tǒng)內(nèi)存空間不足時(shí),被軟引用所引用的JAVA對(duì)象可以被垃圾回收機(jī)制回收,從而避免系統(tǒng)內(nèi)存不足的異常.
            當(dāng)程序需要大量創(chuàng)建某個(gè)類(lèi)的新對(duì)象,而且有可能重新訪問(wèn)已創(chuàng)建老對(duì)象時(shí),可以充分使用軟引用來(lái)解決內(nèi)存緊張的問(wèn)題。
            例如需要訪問(wèn)1000個(gè)Person對(duì)象,可以有兩種方式
            方法一 依次創(chuàng)建1000個(gè)對(duì)象,但只有一個(gè)Person引用指向最后一個(gè)Person對(duì)象
            方法二 定義一個(gè)長(zhǎng)度為1000個(gè)的Person數(shù)組,每個(gè)數(shù)組元素引用一個(gè)Person對(duì)象.
            對(duì)于方法一,弱點(diǎn)很明顯,程序不允許需要重新訪問(wèn)前面創(chuàng)建的Person對(duì)象,即使這個(gè)對(duì)象所占的空間還沒(méi)有被回收。但已經(jīng)失去了這個(gè)對(duì)象的引用,因此也不得不重新創(chuàng)建一個(gè)新的Person對(duì)象(重新分配內(nèi)存),而那個(gè)已有的Person對(duì)象(完整的,正確的,可用的)則只能等待垃圾回收
            對(duì)于方法二,優(yōu)勢(shì)是可以隨時(shí)重新訪問(wèn)前面創(chuàng)建的每個(gè)Person對(duì)象,但弱點(diǎn)也有,如果系統(tǒng)堆內(nèi)存空間緊張,而1000個(gè)Person對(duì)象都被強(qiáng)引用引著,垃圾回收機(jī)制也不可能回收它們的堆內(nèi)存空間,系統(tǒng)性能將變成非常差,甚至因此內(nèi)存不足導(dǎo)致程序中止。
            如果用軟引用則是一種較好的方案,當(dāng)堆內(nèi)存空間足夠時(shí),垃圾回收機(jī)制不會(huì)回收Person對(duì)象,可以隨時(shí)重新訪問(wèn)一個(gè)已有的Person對(duì)象,這和普通的強(qiáng)引用沒(méi)有任何區(qū)別。但當(dāng)heap堆內(nèi)存空間不足時(shí),系統(tǒng)也可以回收軟引用引用的Person對(duì)象,從而提高程序運(yùn)行性能,避免垃圾回收.
            當(dāng)程序使用強(qiáng)引用時(shí),無(wú)論系統(tǒng)堆內(nèi)存如何緊張,JVM垃圾回收機(jī)制都不會(huì)回收被強(qiáng)引用所引用的Java對(duì)象,因此最后導(dǎo)致程序因內(nèi)存不足而中止。但如果把強(qiáng)引用改為軟引用,就完成可以避免這種情況,這就是軟引用的優(yōu)勢(shì)所在.
            (3)弱引用
            弱引用與軟引用有點(diǎn)相似,區(qū)別在于弱引用所引用對(duì)象的生存期更短。弱引用通過(guò)WeakReference類(lèi)實(shí)現(xiàn),弱引用和軟引用很像,但弱引用的引用級(jí)別更低。對(duì)于只有弱引用的對(duì)象而言,當(dāng)系統(tǒng)垃圾回收機(jī)制運(yùn)行時(shí),不管系統(tǒng)內(nèi)存是否足夠,總會(huì)回收該對(duì)象所占用的內(nèi)存。當(dāng)然,并不是說(shuō)當(dāng)一個(gè)對(duì)象只有弱引用時(shí),它就會(huì)立即被回收,正如那些失去引用的對(duì)象一樣,必須等到系統(tǒng)垃圾回收機(jī)制運(yùn)行時(shí)才會(huì)被回收.
            總結(jié)說(shuō)明:
            1.弱引用具有很大的不確定性,因?yàn)槊看卫厥諜C(jī)制執(zhí)行時(shí)都會(huì)回收弱引用所引用的對(duì)象,而垃圾回收機(jī)制的運(yùn)行又不受程序員的控制,因此程序獲取弱引用所引用的java對(duì)象時(shí)必須小心空指針異常,通過(guò)弱引用所獲取的java對(duì)象可能是null
            2.由于垃圾回收的不確定性,當(dāng)程序希望從弱引用中取出被引用對(duì)象時(shí),可能這個(gè)被引用對(duì)象已經(jīng)被釋放了。如果程序需要使用被引用的對(duì)象,則必須重新創(chuàng)建該對(duì)象。
            (4)虛引用
            軟引用和弱引用可以單獨(dú)使用,但虛引用不能單獨(dú)使用,單獨(dú)使用虛引用沒(méi)有太大的意義。虛引用的主要作用就是跟蹤對(duì)象被垃圾回收的狀態(tài),程序可以通過(guò)檢查虛引用關(guān)聯(lián)的引用隊(duì)列中是否包含指定的虛引用,從而了解虛引用所引用的對(duì)象是否將被回收.
            引用隊(duì)列由java.lang.ref.ReferenceQueue類(lèi)表示,它用于保存被回收對(duì)象的引用。當(dāng)把軟引用,弱引用和引用隊(duì)列聯(lián)合使用時(shí),系統(tǒng)回收被引用的對(duì)象之后,將會(huì)把被回收對(duì)象對(duì)應(yīng)的引用添加到關(guān)聯(lián)的引用隊(duì)列中。與軟引用和弱引用不同的是,虛引用在對(duì)象被釋放之前,將把它對(duì)應(yīng)的虛引用添加到關(guān)聯(lián)的隊(duì)列中,這使得可以在對(duì)象被回收之前采取行動(dòng)。
            虛引用通過(guò)PhantomReference類(lèi)實(shí)現(xiàn),它完全類(lèi)似于沒(méi)有引用。虛引用對(duì)對(duì)象本身沒(méi)有大的影響,對(duì)象甚至感覺(jué)不到虛引用的存在。如果一個(gè)對(duì)象只有一個(gè)虛引用,那它和沒(méi)有引用的效果大致相同。虛引用主要用于跟蹤對(duì)象被垃圾回收的狀態(tài),虛引用不能單獨(dú)使用,虛引用必須和隊(duì)列ReferenceQueue聯(lián)合使用.


          posted on 2013-11-15 11:12 順其自然EVO 閱讀(202) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2013年11月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 华亭县| 尤溪县| 平山县| 商都县| 隆安县| 汕尾市| 麻城市| 图木舒克市| 汉寿县| 襄垣县| 武陟县| 苍梧县| 临夏市| 理塘县| 山阴县| 会宁县| 尉氏县| 丰台区| 新建县| 青川县| 乌什县| 清水河县| 柳河县| 昌吉市| 昌黎县| 兴国县| 平遥县| 阿克陶县| 司法| 新绛县| 双柏县| 三门县| 浙江省| 泸定县| 东台市| 祁连县| 杭锦旗| 周至县| 乐安县| 和政县| 大同县|