[轉(zhuǎn)]二、雜談(借此也論一論obj=null)

版權(quán)聲明
作者:zuoxiaolong(左瀟龍)
出處:博客園左瀟龍的技術(shù)博客--http://www.cnblogs.com/zuoxiaolong
您的支持是對博主最大的鼓勵针炉,感謝您的認真閱讀挠他。
本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載篡帕,但未經(jīng)作者同意必須保留此段聲明殖侵,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利镰烧。
原文鏈接:http://www.cnblogs.com/zuoxiaolong/p/jvm2.html

各位園友好拢军,LZ是從某網(wǎng)站轉(zhuǎn)戰(zhàn)過來的博主,看到這里很多博主都稱看友們?yōu)閳@友拌滋,LZ斗膽模仿一下朴沿,不過以前,LZ其實都是稱看友們?yōu)樵秤训陌苌啊V癓Z在某網(wǎng)站已經(jīng)寫了一系列文章赌渣,已經(jīng)全部復(fù)制到了園內(nèi)的新博客,主要是設(shè)計模式的內(nèi)容昌犹,各位有興趣的也可以去翻看一下坚芜,其中有不少還是頗受之前猿友們喜愛的。

作為一個程序猿斜姥,修煉的過程就猶如玄幻小說中的主角鸿竖,不僅需要練習(xí)各種武技,內(nèi)氣的修煉的一樣重要铸敏。雖然武技可以迅速的提升主角的實力缚忧,但是在內(nèi)氣太差的情況下,根本發(fā)揮不出武技的十之一二杈笔。

因此闪水,在介紹過設(shè)計模式這一類外功之后,LZ就直接轉(zhuǎn)戰(zhàn)內(nèi)氣修煉蒙具,和各位猿友探討一下JVM的內(nèi)容球榆。

本來這一章應(yīng)該是介紹與GC相關(guān)的內(nèi)容,不過在此之前禁筏,LZ準備先和各位探討一下一個編程的小技巧持钉。當(dāng)然,這個小技巧其實也是與GC密切相關(guān)的篱昔。

不知道各位猿友有沒看過一些JAVA內(nèi)存相關(guān)的文章每强,里面在羅列建議的時候,經(jīng)常會寫出這樣一條建議。

第XX條空执、請在使用完對象之后窘茁,顯示的將對象設(shè)置為null。

原話不一定如此脆烟,但意思是一樣的。話里所描述的意思房待,就是說我們以后寫代碼應(yīng)該這么寫邢羔。

Object obj = new Object();
//to do something 
obj = null;

這段代碼有點C/C++的風(fēng)格,obj=null代替了C/C++中的delete obj或者是free(obj)桑孩,相當(dāng)于在提示我們拜鹤,就算有了GC,我們也要像沒有GC一樣流椒,使用完對象就得將其賦為空值敏簿。

首先,LZ這里要說明的是宣虾,將obj賦為空值惯裕,與C/C++中的delete其實有著天壤之別,LZ之所以說它們代替了delete和free绣硝,僅僅是因為它們出現(xiàn)在代碼中的位置類似而已蜻势。

obj=null只做了一件事,就是將obj這個引用變量與new Object()創(chuàng)造的實例的關(guān)聯(lián)斷開鹉胖,實際上握玛,實例所占用的內(nèi)存空間依然沒有釋放。

在提出這個建議的時候甫菠,很多博主或者圖書的作者(因為有不少博主估計也是從書上看的)的本意挠铲,是想盡快消除引用與實例的關(guān)聯(lián),從而誘發(fā)GC在進行垃圾回收時寂诱,將實例所占用的內(nèi)存釋放拂苹。在某些時候,這么做也是為了消除內(nèi)存泄露刹衫。

LZ個人覺得醋寝,許多博主或者是圖書作者,提出這個建議的初衷带迟,主要是針對一些沒有接觸過GC原理以及內(nèi)存管理的程序猿而建議的音羞,因為在不明白相關(guān)知識的前提下,很容易掌握不好變量的作用域仓犬,從而導(dǎo)致不必要的內(nèi)存浪費(個人覺得這個并不是主要目的嗅绰,因為只要沒有發(fā)生內(nèi)存泄露,內(nèi)存終究是要被GC釋放的),甚至是內(nèi)存泄露窘面。

所以為了安全起見翠语,有些高人們就提出了這么一個建議。

有鑒于此财边,LZ個人覺得肌括,在各位掌握了相關(guān)知識之后,完全可以忽略這個建議酣难,而且這么做明顯會降低代碼的清晰度以及增加編碼的負擔(dān)谍夭,然而所換來的好處,卻只是為了避免那根本不一定存在的內(nèi)存泄露憨募。

這里解釋一下為何在有些時候不將對象賦為空值會造成內(nèi)存泄露紧索,我們考慮下面一段代碼。

import java.util.Arrays;
public class Stack {
    private static final int INIT_SIZE = 10;
    private Object[] datas;
    private int size;
    public Stack() {
        super();
        datas = new Object[INIT_SIZE];
    }
    public void push(Object data){
        if (size == datas.length) {
            extend();
        }
        datas[size++] = data;
    }
    public Object pop(){
        if (size == 0) {
            throw new IndexOutOfBoundsException("size is zero");
        }
        return datas[--size];
    }
    private void extend(){
        datas = Arrays.copyOf(datas, 2 * size + 1);
    }
}

這段代碼是一個簡單的長度可伸縮的棧實現(xiàn)菜谣,在你寫一段測試代碼去測試它的時候珠漂,會發(fā)現(xiàn)它毫無問題。但是不好意思尾膊,這里面就有一個明顯的“內(nèi)存泄露”媳危,這就是因為一些對象或者說引用沒有設(shè)置為空值所造成的。

如果你還沒看出來眯停,LZ稍微提示一下济舆,各位就會意識到了。這段代碼里面莺债,數(shù)組里的對象只會無限增長滋觉,而不會隨著棧中元素的彈出而減少,減小的僅僅是對外展示的棧的大小size齐邦∽迪溃考慮一個極端的場景,假設(shè)你曾經(jīng)往棧中放入了100萬個對象措拇,最后使用了99萬9千9百9十9個我纪,從外部看來,棧中還只剩一個可用對象了丐吓,但是我們的棧依然持有著100萬個對象的引用浅悉。如果JVM可以活過來的話,想必一定會把你蹂躪到死的券犁。

我們?nèi)鄙俚木褪菍ο筚x為null值的那一步术健,所以pop方法應(yīng)該改為下面的方式,而且各位可以去看一下ArrayList中remove方法的源碼粘衬,也是類似的思路荞估。

public Object pop(){
        if (size == 0) {
            throw new IndexOutOfBoundsException("size is zero");
        }
        Object data = datas[--size];
        datas[size] = null;
        return data;
    }

這個內(nèi)存泄露是非常隱蔽的咳促,而且實際使用當(dāng)中不一定就能發(fā)現(xiàn),因為隨著Stack對象的回收勘伺,整個數(shù)組也會被回收跪腹,到時內(nèi)存泄露就被掩蓋了。

所以個人覺得上述的那個建議是完全沒有必要的飞醉,就算遵從了上面的建議冲茸,如果對內(nèi)存管理不熟悉的話,也不會想到上面這個代碼中的問題缅帘。如果想徹底的避免內(nèi)存泄露的發(fā)生噪裕,機械式的主動將對象賦為空值,并不是一個可以從根本上解決問題的辦法股毫。

真正能夠解決問題的辦法,就是掌握好GC的策略與原理召衔,定義一個變量時多注意變量的作用域铃诬,如此才可以更好的避免內(nèi)存泄露。

所以學(xué)好GC原理還是很有必要的苍凛,希望準備走JAVA之路的朋友趣席,尤其是從培訓(xùn)機構(gòu)出來的猿友們(此處沒有鄙視培訓(xùn)機構(gòu)出來的猿友們的意思,因為LZ本人也是半路出家醇蝴,從培訓(xùn)機構(gòu)走上編程之路的程序猿之一)宣肚,一定不要只專注于各個框架的使用以及業(yè)務(wù)的深入,雖然這些事很有必要悠栓,但并不是全部霉涨。

follow me and go the memory world 吧(語法都是浮云)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惭适,一起剝皮案震驚了整個濱河市笙瑟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌癞志,老刑警劉巖往枷,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異凄杯,居然都是意外死亡错洁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門戒突,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屯碴,“玉大人,你說我怎么就攤上這事妖谴×保” “怎么了酌摇?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嗡载。 經(jīng)常有香客問我窑多,道長,這世上最難降的妖魔是什么洼滚? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任埂息,我火速辦了婚禮,結(jié)果婚禮上遥巴,老公的妹妹穿的比我還像新娘千康。我一直安慰自己,他們只是感情好铲掐,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布拾弃。 她就那樣靜靜地躺著,像睡著了一般摆霉。 火紅的嫁衣襯著肌膚如雪豪椿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天携栋,我揣著相機與錄音搭盾,去河邊找鬼。 笑死婉支,一個胖子當(dāng)著我的面吹牛鸯隅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播向挖,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝌以,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了何之?” 一聲冷哼從身側(cè)響起饼灿,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎帝美,沒想到半個月后碍彭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡悼潭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年庇忌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舰褪。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡皆疹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出占拍,到底是詐尸還是另有隱情略就,我是刑警寧澤捎迫,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站表牢,受9級特大地震影響窄绒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜崔兴,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一彰导、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敲茄,春花似錦位谋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秆剪,卻和暖如春损同,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸟款。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茂卦,地道東北人何什。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像等龙,于是被迫代替她去往敵國和親处渣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,147評論 25 707
  • 一. 垃圾回收的意義 在C++中蛛砰,對象所占的內(nèi)存在程序結(jié)束運行之前一直被占用罐栈,在明確釋放之前不能分配給其它對...
    Stan_Z閱讀 1,932評論 0 25
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司泥畅,掛了不少荠诬,但最終還是拿到小米、百度位仁、阿里柑贞、京東、新浪聂抢、CVTE钧嘶、樂視家的研發(fā)崗...
    時芥藍閱讀 42,251評論 11 349
  • 你裝著玩笑說千萬別喜歡我, 我裝作玩笑說死也不會喜歡你琳疏。 我們沒可能的有决, 我都知道的闸拿, 但是, 我就是很喜歡你啊
    朝花惜時憶蟬鳴閱讀 119評論 0 0
  • 隱約記得,那時我十四歲按咒,她大約是十三歲罷迟隅。 我坐在她的后面,而她坐在我的前面励七,即是同學(xué)智袭,雖然過了好久的時日,但她也...
    從周閱讀 750評論 13 18