<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-144  評(píng)論-80  文章-1  trackbacks-0
    很多人在談?wù)搩?nèi)存泄露問題,當(dāng)然對(duì)于c/c++來說,這個(gè)應(yīng)該是老掉牙的問題,但是很多Java人員也越來越多得討論這個(gè)問題,我這里寫個(gè)小結(jié),希望對(duì)大家有一定的參考價(jià)值。

      內(nèi)存泄漏的慨念

      1.c/c++是程序員自己管理內(nèi)存,Java內(nèi)存是由GC自動(dòng)回收的。

      我雖然不是很熟悉C++,不過這個(gè)應(yīng)該沒有犯常識(shí)性錯(cuò)誤吧。

      2.什么是內(nèi)存泄露?

      內(nèi)存泄露是指系統(tǒng)中存在無(wú)法回收的內(nèi)存,有時(shí)候會(huì)造成內(nèi)存不足或系統(tǒng)崩潰。

      在C/C++中分配了內(nèi)存不釋放的情況就是內(nèi)存泄露。

      3.Java存在內(nèi)存泄露

      我們必須先承認(rèn)這個(gè),才可以接著討論。雖然Java存在內(nèi)存泄露,但是基本上不用很關(guān)心它,特別是那些對(duì)代碼本身就不講究的就更不要去關(guān)心這個(gè)了。

      Java中的內(nèi)存泄露當(dāng)然是指:存在無(wú)用但是垃圾回收器無(wú)法回收的對(duì)象。而且即使有內(nèi)存泄露問題存在,也不一定會(huì)表現(xiàn)出來。

      4.Java中參數(shù)都是傳值的。

      對(duì)于基本類型,大家基本上沒有異議,但是對(duì)于引用類型我們也不能有異議。

      Java內(nèi)存泄露情況

      JVM回收算法是很復(fù)雜的,我也不知道他們?cè)趺磳?shí)現(xiàn)的,但是我只知道他們要實(shí)現(xiàn)的就是:對(duì)于沒有被引用的對(duì)象是可以回收的。所以你要造成內(nèi)存泄露就要做到:

      持有對(duì)無(wú)用對(duì)象的引用!

      不要以為這個(gè)很容易做到,既然無(wú)用,你怎么還會(huì)持有它的引用? 既然你還持有它,它怎么會(huì)是無(wú)用的呢?

      我實(shí)在想不到比那個(gè)堆棧更經(jīng)典的例子了,以致于我還要引用別人的例子,下面的例子不是我想到的,是書上看到的,當(dāng)然如果沒有在書上看到,可能過一段時(shí)間我自己也想的到,可是那時(shí)我說是我自己想到的也沒有人相信的。

    public class Stack {
     private Object[] elements=new Object[10];
     private int size = 0;

     public void push(Object e){
      ensureCapacity();
      elements[size++] = e;
     }

     public Object pop(){
      if( size == 0)
       throw new EmptyStackException();
       return elements[--size];
     }

    private void ensureCapacity(){
     if(elements.length == size){
      Object[] oldElements = elements;
      elements = new Object[2 * elements.length+1];
      System.arraycopy(oldElements,0, elements, 0, size);
     }
    }
    }

      上面的原理應(yīng)該很簡(jiǎn)單,假如堆棧加了10個(gè)元素,然后全部彈出來,雖然堆棧是空的,沒有我們要的東西,但是這是個(gè)對(duì)象是無(wú)法回收的,這個(gè)才符合了內(nèi)存泄露的兩個(gè)條件:無(wú)用,無(wú)法回收。

      但是就是存在這樣的東西也不一定會(huì)導(dǎo)致什么樣的后果,如果這個(gè)堆棧用的比較少,也就浪費(fèi)了幾個(gè)K內(nèi)存而已,反正我們的內(nèi)存都上G了,哪里會(huì)有什么影響,再說這個(gè)東西很快就會(huì)被回收的,有什么關(guān)系。下面看兩個(gè)例子。

      例子1

    public class Bad{
     public static Stack s=Stack();
      static{
       s.push(new Object());
       s.pop(); //這里有一個(gè)對(duì)象發(fā)生內(nèi)存泄露
       s.push(new Object()); //上面的對(duì)象可以被回收了,等于是自愈了
      }
    }

      因?yàn)槭莝tatic,就一直存在到程序退出,但是我們也可以看到它有自愈功能,就是說如果你的Stack最多有100個(gè)對(duì)象,那么最多也就只有100個(gè)對(duì)象無(wú)法被回收其實(shí)這個(gè)應(yīng)該很容易理解,Stack內(nèi)部持有100個(gè)引用,最壞的情況就是他們都是無(wú)用的,因?yàn)槲覀円坏┓判碌倪M(jìn)取,以前的引用自然消失!

      例子2

    public class NotTooBad{
     public void doSomething(){
      Stack s=new Stack();
      s.push(new Object());
      //other code
      s.pop();//這里同樣導(dǎo)致對(duì)象無(wú)法回收,內(nèi)存泄露.
     }//退出方法,s自動(dòng)無(wú)效,s可以被回收,Stack內(nèi)部的引用自然沒了,所以
     //這里也可以自愈,而且可以說這個(gè)方法不存在內(nèi)存泄露問題,不過是晚一點(diǎn)
     //交給GC而已,因?yàn)樗欠忾]的,對(duì)外不開放,可以說上面的代碼99.9999%的
     //情況是不會(huì)造成任何影響的,當(dāng)然你寫這樣的代碼不會(huì)有什么壞的影響,但是
     //絕對(duì)可以說是垃圾代碼!沒有矛盾吧,我在里面加一個(gè)空的for循環(huán)也不會(huì)有
     //什么太大的影響吧,你會(huì)這么做嗎?
    }

      上面兩個(gè)例子都不過是小打小鬧,但是C/C++中的內(nèi)存泄露就不是Bad了,而是Worst了。他們?nèi)绻惶帥]有回收就永遠(yuǎn)無(wú)法回收,頻繁的調(diào)用這個(gè)方法內(nèi)存不就用光了!因?yàn)镴ava還有自愈功能(我自己起的名字,還沒申請(qǐng)專利),所以Java的內(nèi)存泄露問題幾乎可以忽略了,但是知道的人就不要犯了。

      不知者無(wú)罪!Java存在內(nèi)存泄露,但是也不要夸大其辭。如果你對(duì)Java都不是很熟,你根本就不用關(guān)心這個(gè),我說過你無(wú)意中寫出內(nèi)存泄露的例子就像你中一千萬(wàn)一樣概率小,開玩笑了,其實(shí)應(yīng)該是小的多的多!

      而且即使你有幸寫出這樣的代碼,中獎(jiǎng)了!基本上都是一包洗衣粉,不會(huì)讓你發(fā)財(cái),對(duì)系統(tǒng)沒有什么大的影響。

      杞人憂天的情況

      1.無(wú)話可說型

    Object obj=new Object();
    obj=null;
    //這個(gè)完全多此一舉,因?yàn)橥顺隽俗饔梅秶瑢?duì)象的引用自動(dòng)消失
    //不要在你的程序中出現(xiàn)這樣的語(yǔ)句,沒有錯(cuò),但是就是不雅觀

      2.思考不對(duì)型

    void func(Object o){
     o=new Object();
     return
    }

      當(dāng)我們知道Java參數(shù)是傳值,就知道上面的方法什么也沒錯(cuò),就是申請(qǐng)了一個(gè)對(duì)象然后再丟給GC。因?yàn)槭莻髦担@里的o是一個(gè)調(diào)用時(shí)候的拷貝,會(huì)不會(huì)無(wú)法回收?不就是拷貝嗎,退出方法什么都沒了,這個(gè)對(duì)象怎么會(huì)留的住。

      3.盡量避免型

    class A{
     B b=new B(this);
    }
    class B{
     A a;
     B(A a){this.a=a;}
    }

      這個(gè)存在互相引用,可能導(dǎo)致孤島現(xiàn)象,但是這個(gè)不會(huì)造成內(nèi)存泄露不過我自己覺得這個(gè)會(huì)降低GC的效率,就從我的智力來看,我覺得這種情況比一般情況難以判斷怎么回收!當(dāng)然GC比我聰明,不過應(yīng)該也要?jiǎng)右稽c(diǎn)腦子吧。
    posted on 2005-03-11 09:35 小力力力 閱讀(241) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA
    主站蜘蛛池模板: 毛片免费在线视频| 亚洲国产精品尤物YW在线观看| 亚洲一级视频在线观看| 天天摸天天碰成人免费视频| 免费无码A片一区二三区 | 亚洲天堂久久精品| 成年大片免费高清在线看黄| 亚洲国产一成人久久精品| 黄页免费视频播放在线播放| 亚洲免费人成在线视频观看| 日本XXX黄区免费看| 九九免费精品视频在这里| 亚洲精品自产拍在线观看动漫 | 久久久久久久尹人综合网亚洲| 精品无码国产污污污免费网站 | 亚洲色偷拍另类无码专区| 最近中文字幕mv免费高清在线| 亚洲爆乳成av人在线视菜奈实| 久久激情亚洲精品无码?V| 久久九九兔免费精品6| jzzijzzij在线观看亚洲熟妇| 久久综合日韩亚洲精品色| 日本高清免费中文字幕不卡| 久久免费福利视频| 免费激情网站国产高清第一页 | 亚洲最大的成人网| 亚洲欧洲日产国码av系列天堂| 午夜视频在线观看免费完整版| 国产激情免费视频在线观看| 黄页网站在线视频免费| 亚洲图片校园春色| 亚洲人成色77777| 四虎永久免费网站免费观看| 无码区日韩特区永久免费系列 | 成人免费在线视频| 久久一区二区三区免费播放| 高清免费久久午夜精品| 亚洲免费综合色在线视频| 亚洲欧洲精品视频在线观看| 久久精品国产69国产精品亚洲| 国产亚洲福利一区二区免费看|