JAVA中內(nèi)存泄漏的情況

一锁蠕、什么是內(nèi)存泄漏夷野?

這句話可能有點(diǎn)繞:當(dāng)一個(gè)長(zhǎng)生命周期的對(duì)象持有一個(gè)短生命周期的對(duì)象的引用時(shí),導(dǎo)致短生命周期的對(duì)象無(wú)法被回收荣倾,而導(dǎo)致我們寶貴的內(nèi)存被占用,最終OOM,全稱“Out Of Memory”,翻譯成中文就是“內(nèi)存用完了悯搔。

大家都知道在JAVA中有著名的垃圾回收器GC,那么GC是如何認(rèn)識(shí)垃圾的呢舌仍?有兩種常用的方式1.引用計(jì)數(shù)法? 2.根可達(dá)算法妒貌,可無(wú)論是引用計(jì)數(shù)還是根可達(dá)算法都是根據(jù)引用來(lái)判斷對(duì)象到底是不是一個(gè)垃圾,要不要回收它铸豁,可現(xiàn)在有這么一種情況? 如圖所示:



對(duì)象A生命周期明明是到T1就結(jié)束了(引用應(yīng)該釋放掉灌曙,被GC發(fā)現(xiàn)應(yīng)該回收內(nèi)存),但是生命周期為T2的對(duì)象B霸占了對(duì)象A的引用導(dǎo)致對(duì)象A不能被回收节芥。


2在刺、內(nèi)存泄漏的具體情況

(1)靜態(tài)集合類:

如HashMap、LinkedList头镊、ArrayList等等蚣驼。如果這些容器為靜態(tài)的,那么它們的生命周期與程序一致相艇,則容器中的對(duì)象在程序結(jié)束之前將不能被釋放颖杏,從而造成內(nèi)存泄漏。簡(jiǎn)單而言坛芽,長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用留储,盡管短生命周期的對(duì)象不再使用,但是因?yàn)殚L(zhǎng)生命周期對(duì)象持有它的引用而導(dǎo)致不能被回收咙轩,解決辦法是最好不使用靜態(tài)的集合類获讳,如果使用的話,在不需要容器時(shí)要將其賦值為null活喊。

(2)創(chuàng)建的各種連接赔嚎,數(shù)據(jù)庫(kù)連接,IO連接等等

例如我們?cè)谶B接數(shù)據(jù)庫(kù)的時(shí)候像JDBC六大步胧弛,注冊(cè)驅(qū)動(dòng)尤误,獲取連接,創(chuàng)建連接對(duì)象结缚,執(zhí)行sql损晤,處理結(jié)果集,釋放資源红竭,這是時(shí)候的釋放資源調(diào)用close()方法就是告訴GC尤勋,這個(gè)連接對(duì)象我不用了喘落,你可以回收了,如果你不釋放最冰,GC是無(wú)法判定你有沒(méi)有使用完連接對(duì)象的瘦棋,自然不能幫你釋放資源,從而暖哨,你在使用數(shù)據(jù)庫(kù)的時(shí)候會(huì)產(chǎn)生大量的對(duì)象赌朋,對(duì)資源進(jìn)行浪費(fèi),導(dǎo)致內(nèi)存泄漏篇裁。

(3)變量不合理的作用域

可以聲明為局部變量(在方法中)絕不聲明為成員變量(在類中) 因?yàn)榫植孔兞渴请S著方法的調(diào)用而創(chuàng)建沛慢,隨著方法的銷毀而銷毀,而定義為成員變量是隨著類在變化达布,在方法中用完之后沒(méi)有設(shè)為null值团甲,那么便會(huì)隨著類一直存在造成內(nèi)存泄漏。

(4)內(nèi)部類持有外部類

如果一個(gè)外部類的實(shí)例對(duì)象的方法返回了一個(gè)內(nèi)部類的實(shí)例對(duì)象黍聂,這個(gè)內(nèi)部類對(duì)象被長(zhǎng)期引用了躺苦,即使那個(gè)外部類實(shí)例對(duì)象不再被使用,但由于內(nèi)部類持有外部類的實(shí)例對(duì)象产还,這個(gè)外部類對(duì)象將不會(huì)被垃圾回收匹厘,這也會(huì)造成內(nèi)存泄露。

(5)緩存泄漏

內(nèi)存泄漏的另一個(gè)常見(jiàn)來(lái)源是緩存雕沉,一旦你把對(duì)象引用放入到緩存中集乔,他就很容易遺忘去件,對(duì)于這個(gè)問(wèn)題坡椒,可以使用WeakHashMap代表緩存,此種Map的特點(diǎn)是尤溜,當(dāng)除了自身有對(duì)key的引用外倔叼,此key沒(méi)有其他引用那么此map會(huì)自動(dòng)丟棄此值

``

public class Test {

public static void main(String[] args) {

String a =new String("a");

String b =new String("b");

Map map =new HashMap();

map.put(a,"aaa");

map.put(b,"bbb");

Map weakmap =new WeakHashMap();

weakmap.put(a,"aaa");

weakmap.put(b,"bbb");

map.remove(a);

a =null; b =null;

System.gc();

map.forEach((i1,i2)->{

System.out.println("map:");

System.out.println(i1+":"+i2);});

weakmap.forEach((i1,i2)->{

System.out.println("weakmap:");

System.out.println(i1+":"+i2);

});

}

}

``

輸出結(jié)果如下,看一下代碼你發(fā)下只是移除了map中的a宫莱,weakmap中的a也消失了

(6)改變哈希值

當(dāng)一個(gè)對(duì)象被存儲(chǔ)進(jìn)HashSet集合中以后丈攒,就不能修改這個(gè)對(duì)象中的那些參與計(jì)算哈希值的字段了,否則授霸,對(duì)象修改后的哈希值與最初存儲(chǔ)進(jìn)HashSet集合中時(shí)的哈希值就不同了巡验,在這種情況下,即使在contains方法使用該對(duì)象的當(dāng)前引用作為的參數(shù)去HashSet集合中檢索對(duì)象碘耳,也將返回找不到對(duì)象的結(jié)果显设,這也會(huì)導(dǎo)致無(wú)法從HashSet集合中單獨(dú)刪除當(dāng)前對(duì)象,造成內(nèi)存泄露

(7)單例模式可能會(huì)造成內(nèi)存泄露

? ? 單例模式只允許應(yīng)用程序存在一個(gè)實(shí)例對(duì)象辛辨,并且這個(gè)實(shí)例對(duì)象的生命周期和應(yīng)用程序的生命周期一樣長(zhǎng)捕捂,如果單例對(duì)象中擁有另一個(gè)對(duì)象的引用的話瑟枫,這個(gè)被引用的對(duì)象就不能被及時(shí)回收。解決辦法是單例對(duì)象中持有的其他對(duì)象使用弱引用指攒,弱引用對(duì)象在GC線程工作時(shí)慷妙,其占用的內(nèi)存會(huì)被回收掉,不知道什么是弱引用的可以看我之前文章允悦,強(qiáng)軟弱虛膝擂。

(8)監(jiān)聽(tīng)器和回調(diào)

內(nèi)存泄漏第三個(gè)常見(jiàn)來(lái)源是監(jiān)聽(tīng)器和其他回調(diào),如果客戶端在你實(shí)現(xiàn)的API中注冊(cè)回調(diào)澡屡,卻沒(méi)有顯示的取消猿挚,那么就會(huì)積聚。需要確笔火模回調(diào)立即被當(dāng)作垃圾回收的最佳方法是只保存他的若引用绩蜻,例如將他們保存成為WeakHashMap中的鍵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末室埋,一起剝皮案震驚了整個(gè)濱河市办绝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姚淆,老刑警劉巖孕蝉,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腌逢,居然都是意外死亡降淮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門搏讶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)佳鳖,“玉大人,你說(shuō)我怎么就攤上這事媒惕∠捣裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵妒蔚,是天一觀的道長(zhǎng)穿挨。 經(jīng)常有香客問(wèn)我,道長(zhǎng)肴盏,這世上最難降的妖魔是什么科盛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮菜皂,結(jié)果婚禮上贞绵,老公的妹妹穿的比我還像新娘。我一直安慰自己幌墓,他們只是感情好但壮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布冀泻。 她就那樣靜靜地躺著,像睡著了一般蜡饵。 火紅的嫁衣襯著肌膚如雪弹渔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天溯祸,我揣著相機(jī)與錄音肢专,去河邊找鬼。 笑死焦辅,一個(gè)胖子當(dāng)著我的面吹牛博杖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筷登,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼剃根,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了前方?” 一聲冷哼從身側(cè)響起狈醉,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惠险,沒(méi)想到半個(gè)月后苗傅,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡班巩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年渣慕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抱慌。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逊桦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遥缕,到底是詐尸還是另有隱情卫袒,我是刑警寧澤宵呛,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布单匣,位于F島的核電站,受9級(jí)特大地震影響宝穗,放射性物質(zhì)發(fā)生泄漏户秤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一逮矛、第九天 我趴在偏房一處隱蔽的房頂上張望鸡号。 院中可真熱鬧,春花似錦须鼎、人聲如沸鲸伴。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汞窗。三九已至姓赤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仲吏,已是汗流浹背不铆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裹唆,地道東北人誓斥。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像许帐,于是被迫代替她去往敵國(guó)和親劳坑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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