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

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

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

    一葉笑天
    雄關漫道真如鐵, 而今邁步從頭越。 從頭越, 蒼山如海, 殘陽如血。
    posts - 73,comments - 7,trackbacks - 0
    Java語言中給人的印象是不需要考慮內存管理,但是這種理解是不正確的,看下面的簡單stack實現代碼:
     1// Can you spot the "memory leak"?
     2public class Stack {
     3    private Object[] elements;
     4    private int size = 0;
     5    private static final int DEFAULT_INITIAL_CAPACITY = 16;
     6
     7    public Stack() {
     8        elements = new Object[DEFAULT_INITIAL_CAPACITY];
     9    }

    10
    11    public void push(Object e) {
    12        ensureCapacity();
    13        elements[size++= e;
    14    }

    15
    16    public Object pop() {
    17        if (size == 0)
    18            throw new EmptyStackException();
    19        return elements[--size];
    20    }

    21
    22    /**
    23     * Ensure space for at least one more element, roughly doubling the capacity
    24     * each time the array needs to grow.
    25     */

    26    private void ensureCapacity() {
    27        if (elements.length == size)
    28            elements = Arrays.copyOf(elements, 2 * size + 1);
    29    }

    30}
            這段代碼看上去沒有什么錯,每次測試的時候都可以成功。但是這里有一個潛在的問題,泛義的講就是程序存在內存泄漏,由于不斷增加的垃圾回收器活動或者增加的內存訪問,而使性能降低被暴露出來。極端情況下,這種內存泄漏會導致磁盤頁面訪問甚至程序出現OutOfMemoryError的錯誤。但是這種錯誤是很少出現的。
          當stack增長和收縮時,即使程序不再使用它們,出棧的對象不會被垃圾收集。由于stack維護著這些對象的過時的引用。這種過時的引用是一種不再被重新引用的簡單引用。在這種情況下,任何出了活動區的元素引用都是過時的。活動區包含著一個小于size的元素index。
            具有垃圾回收器的語言,也稱為無意的對象保持,內存泄漏是潛在的。如果一個對象是無意的保持,不僅垃圾回收器不能包含他們,而且其他任何對象也不能引用它們。
           修改這種錯誤的方法很簡單,一旦他們不再使用,設置它的引用為null。例如stack類,當元素出棧后就會變成不再使用的對性。正確的pop函數應該這樣寫:
    1public Object pop() {
    2if (size == 0)
    3throw new EmptyStackException();
    4Object result = elements[--size];
    5elements[size] = null// Eliminate obsolete reference
    6return result;
    7}
         設置過時的對象引用為null的另外一個好處是,如果它們被錯誤的重新引用,程序會立即拋出NullPointerException,而不是靜靜的做錯誤的事情。
         當程序員第一次遇到這種問題后,他們可能會過度在每個對象引用后設置為null。這是不需要而且不可取的。設置對象引用為null應該是一個例外,而不是一個準則。消除這種過時對象引用的最好方法是讓包含引用的變量在范圍外訪問時發生錯誤。
           設置引用為null的時機是什么?Stack的的那些方面容易遭受內存泄漏?簡單的說就是管理自己的內存。存儲池保持著一個元素列表,這個列表中處于活動區的元素是被分配的。列表中剩余的元素是空閑的。垃圾回收器不知道這些。對于垃圾回收器,所有列表中的元素都是有效的。只有程序員知道列表中不活動的部分是不重要的。程序員只有設置不活動的部分為null時,垃圾回收器才能感知到。
        總的來說,任何時候,當一個類管理自己的內存,程序員應該警惕內存泄漏。當元素釋放的時候,包含元素的對象引用應該設置為null。
        另外一個內存泄漏的例子是緩存cache。當你把一個對象引用放進cache,很容易遺忘掉在它變為不相關的時候它還在cache中。解決這種問題的方法是將cache表示成為一個WeakHashMap,入口點將會在他們過時的時候自動刪除。記住,WeakHashMap只在當一個期望的cache入口在被外面的引用到key,而不是值的時候才是有用的。
         更為常見的是,cache的缺少好的有用生命周期定義。在這種情況下,cache應該在當entry沒有用的時候清除它們。可以通過后臺線程(Timer或者ScheduledThreadPoolExecutor)或者as a side effect of adding new entries to the cache來實現。LinkedHashMap類用removeEldestEntry方法實現了后者方式。對于好的cache,應該直接使用java.lang.ref。
         第三種常見的內存泄漏的例子就是監聽器和一些回調listeners and other callbacks.如果你實現一個API,客戶注冊回調但是不顯式的注銷回調,它們就會堆積起來,除非你采取措施。確保回調被垃圾回收的最好方式是存儲weak reference給它們,例如將它們僅僅作為key存儲在WeakHashMap中。
         因為內存泄漏是典型的沒有明顯的錯誤特征,它們可能在一個系統中保持數年。但是它們可以被仔細的代碼檢查或者heap profiler這樣的調試工具發現。因此,需要預知這些問題而且避免它們的發生。

    posted on 2008-06-23 10:53 一葉笑天 閱讀(379) 評論(0)  編輯  收藏 所屬分類: JAVA技術
    主站蜘蛛池模板: 亚洲一级特黄特黄的大片| 美女视频黄免费亚洲| 国产高清对白在线观看免费91 | a级片免费在线观看| 亚洲视频人成在线播放| 免费国产高清毛不卡片基地| 国产中文字幕免费| 特黄特色的大片观看免费视频| 亚洲AV无码乱码在线观看性色扶| 国产av无码专区亚洲av毛片搜| 免费人成在线观看播放国产 | 成人无码视频97免费| 亚洲免费人成在线视频观看| 中文字幕日本人妻久久久免费| 亚洲AV永久无码区成人网站 | 中文字幕亚洲日韩无线码| WWW免费视频在线观看播放| 亚洲AV综合色区无码一区爱AV| 久久精品国产影库免费看| 亚洲码一区二区三区| 亚洲视频在线观看视频| 免费观看无遮挡www的视频| 亚洲日韩中文字幕无码一区| 免费人成无码大片在线观看| 91成人免费福利网站在线| 亚洲综合色丁香麻豆| 全免费一级毛片在线播放| 水蜜桃视频在线观看免费| 亚洲国产天堂在线观看| 好男人www免费高清视频在线| 免费视频精品一区二区| 久久精品视频亚洲| 国产大片51精品免费观看| 永久免费A∨片在线观看| 亚洲av一本岛在线播放| 亚洲国产精品成人AV无码久久综合影院| 免费网站观看WWW在线观看| 亚洲日本VA午夜在线电影| 亚洲欧洲日产国码无码网站| 亚洲成在人线aⅴ免费毛片| 国产97视频人人做人人爱免费|