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

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

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

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0
    第六條:消除過期的對象引用
      
      1.當你從手工管理內存的語言,如C或者C++轉換到具有垃圾回收功能的語言的時候,程序員的工作會變得更加容易,因為當你用完了對象之后,他們會被自動回收。當你認為自己不需要在考慮內存管理的事情時,其實則不然:
      2.參見Stack:消除過期的對象引用的一個例子,非泛型版本
             * <pre>
           * 1.不嚴格的講,這段程序有一個內存泄露,隨著垃圾回收器活動的增加,或者由于內存占用的不斷增加,程序性能的降低會逐漸表現出來。
           * 2.在極端的情況下,這種內存泄露會導致磁盤交換,Disk paging,甚至導致程序失敗OutOfMemoryError,不過這種失敗情形相對比較少見
           * 3.如果一個棧先是增長然后再收縮,那么從棧中彈出來的對象將不會被當做垃圾回收,即使使用棧的程序不再引用這些對象,它們也不會被回收。這是因為棧內部維護著這些對象的過期引用obsolete reference.所謂的過期引用,是指永遠也不會再被解除的引用。在本例中,凡是elements數組中的活動部分
           * active portion之外的任何引用都是過期的。活動部分是指elements中下標小于size的那些元素.因為被彈出棧的元素,即大于size的且依然保存在elements
           * 數組中的不會被回收.
           * </pre>
      3.在支持垃圾回收的語言中,內存泄露是很隱藏的。稱該類內存泄露為無意識的對象保持unintentional object retention更為恰當。如果一個對象引用被無意識的保留起來,那么垃圾回收機制不僅不會處理這個對象,而且也不會處理被這個對象所引用的所有其他對象。即使只有少量的幾個對象引用被無意識的保留下來,也會有許許多多的地方唄排除在垃圾回收機制之外,從而對性能造成潛在的重大影響。
      4.修復方法很簡單:一旦對象引用已經過期,只需清空這些引用即可。對于該例,只要一個單元被彈出棧指向它的引用就過期了。
      5.清空過期引用的另一個好處是,如果他們以后又被錯誤的解除引用,程序就會立刻拋出NullPointerException異常,而不是悄悄的錯誤運行下去。盡快的檢測出程序中的錯誤總是有益的。
      6.清空對象引用應該是一種例外,而不是一種規范行為。消除過期引用最好的辦法是讓包含該引用的變量結束其生命周期。如果你是最緊湊的作用域范圍內定義一個變量,這種情形就會自然而然的發生。
      7.Stack之所以易于遭受內存泄露的影響,問題在于Stack自己管理內存manage its own memory.存儲池storage pool包含了elments數組,對象引用單元而不是對象本身。的元素。數組活動區域中的元素是已分配的,而數組其余部分的元素則是自由的。但是垃圾回收期并不知道這一點,對于其而言,elements數組中的所有對象引用都同等有效。只有程序員知道數組的非活動部分是不重要的,程序員可以把這個情況告訴垃圾回收器。做法很簡單,一旦數組元素變成了非活動部分的一部分,程序員就手動清空這些數組元素。一般而言,只要類時自己管理內存,程序員就應該警惕內存泄露問題。一旦元素被釋放掉,則該元素中包含的任何對象引用都 應該被清空。
      8.內存泄露的另一個常見來源是緩存。一旦你把對象放到緩存中,它就很容易被遺忘掉,而從使得他不再有用之后很長一段時間內仍然留在緩存中。對于這個問題,有幾種可能解決的方案。如果你正要實現這樣的緩存:只要在緩存之外存在對某個項的鍵的引用,該項就有意義。那么就可以用WeakHashMap代表緩存,當緩存中的項過期之后,他們就會自動被刪除。記住只有當所要的緩存項的生命周期是由該鍵的外部引用而不是用值決定時,WeakHashMap才有用處。
      9.更為常見的情形則是:緩存的聲明周期是否有意義并不是很容易確定。隨著時間的推移,其中的項會變得越來越沒有價值。在這種情況下,緩存應該時不時的清除沒用的項。這項清除工作可以由一個后臺線程可能是Timer或者ScheduledThreadPoolExecutor來完成或者也可以給緩存添加新條目的時候順便清理。LinkedHashMap類利用它的removeElderestEntry方法可以很容易的實現后一種方案.(注:LRU),對于更加復雜的緩存,必須直接使用java.lang.ref.
      10.內存泄露的第三個常見來源是監聽器和其他回調。如果你實現了一個API,client在這個API中注冊回調,卻沒有顯示的取消注冊。那么除非你采取某些動作,否則他們就會積聚。確保回調立即被當做垃圾回收的最佳方式是只保存他們的弱引用weak reference。例如,至將他們保存成WeakHashMap中的鍵。
      11.由于內存泄露通常不會表現為明顯的失敗,所以他們可以在一個系統中存很多年。往往只有通過仔細檢查代碼或者借助于Heap剖析工具Heap Profiler才能發現內存泄露問題。因此,如果能夠在內存泄露之前就知道如何預測此問題的話并阻止他們發生,那最好不過

    部分源碼:
    package com.book.chap2.clearOverdueRef;

    import java.util.Arrays;
    import java.util.EmptyStackException;

    /**
    *
    * 消除過期的對象引用的一個例子,非泛型版本
    * <pre>
    * 1.不嚴格的講,這段程序有一個內存泄露,隨著垃圾回收器活動的增加,或者由于內存占用的不斷增加,程序性能的降低會逐漸表現出來。
    * 2.在極端的情況下,這種內存泄露會導致磁盤交換,Disk paging,甚至導致程序失敗OutOfMemoryError,不過這種失敗情形相對比較少見
    * 3.如果一個棧先是增長然后再收縮,那么從棧中彈出來的對象將不會被當做垃圾回收,即使使用棧的程序不再引用這些對象,它們也不會被回收。這是因為棧內部
    * 維護著這些對象的過期引用obsolete reference.所謂的過期引用,是指永遠也不會再被解除的引用。在本例中,凡是elements數組中的活動部分
    * active portion之外的任何引用都是過期的。活動部分是指elements中下標小于size的那些元素.因為被彈出棧的元素,即大于size的且依然保存在elements
    * 數組中的不會被回收.
    * </pre>
    *
    * @author landon
    * @since 1.6.0_35
    * @version 1.0.0 2013-3-12
    *
    */


    public class Stack
    {
       
    private Object[] elements;
       
    private int size = 0;
       
    private static final int DEFAULT_INITIAL_CAPACITY = 10;
       
       
    public Stack()
       
    {
            elements = new Object[DEFAULT_INITIAL_CAPACITY];
        }

       
       
    /**
         * 入棧
         * @param e
        
    */

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

       
       
    /**
         * 彈棧
         * @return
        
    */

       
    public Object pop()
       
    {
           
    if(size == 0)
           
    {
               
    throw new EmptyStackException();
            }

           
           
    return elements[--size];
        }

       
       
    /**
         * 修復pop:一旦對象引用已經過期,只需清空這些引用即可。對于該例,只要一個單元被彈出棧指向它的引用就過期了。
         * @return
        
    */

       
    public Object gcPop()
       
    {
           
    if(size == 0)
           
    {
               
    throw new EmptyStackException();
            }

           
            Object result = elements[--size];
           
    //置null,移除過期引用
            elements[size] = null;
           
           
    return result;
        }

       
       
    /**
         * 超出空間后,擴展空間
        
    */

       
    public void e    nsureCapacity()
    {
           
    if(elements.length == size)
           
    {
                elements
    = Arrays.copyOf(elements, 2 * size + 1);
            }

        }

    }

    posted on 2013-03-15 19:15 landon 閱讀(1841) 評論(0)  編輯  收藏 所屬分類: ProgramBook
    主站蜘蛛池模板: 亚洲中文久久精品无码ww16| 国产午夜亚洲精品理论片不卡 | 免费久久人人爽人人爽av| 日日操夜夜操免费视频 | 国产成人va亚洲电影| 日本人护士免费xxxx视频| 亚洲sm另类一区二区三区| 免费无码又爽又高潮视频| 亚洲AV无码专区亚洲AV桃| 四虎免费永久在线播放| 亚洲精品黄色视频在线观看免费资源 | 美女免费精品高清毛片在线视| 免费人成视频x8x8入口| 一级做a爰片久久毛片免费陪| 亚洲片国产一区一级在线观看| 一级毛片免费播放男男| 国产精一品亚洲二区在线播放| 久久aa毛片免费播放嗯啊| 在线观看亚洲人成网站| 在线看免费观看AV深夜影院| 亚洲一本到无码av中文字幕| 国产成人免费手机在线观看视频| 又硬又粗又长又爽免费看 | 青青草无码免费一二三区| 亚洲国产精品成人精品小说| A级毛片内射免费视频| 色婷婷亚洲一区二区三区| 久久国产成人精品国产成人亚洲| 亚洲一区二区在线免费观看| 亚洲国产成人久久77| 在线日韩av永久免费观看| 国产精品免费看久久久香蕉| 91亚洲国产成人精品下载| 国产精品美女自在线观看免费| 中文无码日韩欧免费视频| 亚洲码一区二区三区| 亚洲A∨午夜成人片精品网站| 七色永久性tv网站免费看| 中国亚洲呦女专区| 国产亚洲AV夜间福利香蕉149| 黄色永久免费网站|