<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技術
    主站蜘蛛池模板: 国产乱子伦精品免费无码专区 | 免费萌白酱国产一区二区三区 | 成人国产mv免费视频| 999久久久免费精品国产| 亚洲av无码乱码国产精品| 永久免费不卡在线观看黄网站| 精品国产亚洲一区二区在线观看| 特级毛片aaaa级毛片免费| 日韩免费人妻AV无码专区蜜桃| 免费看男女下面日出水视频| 久久亚洲精品无码av| 无码专区一va亚洲v专区在线| 狼色精品人妻在线视频免费| 亚洲?v无码国产在丝袜线观看| 免费福利在线观看| 青青草原亚洲视频| 国产午夜精品久久久久免费视| 国产无遮挡色视频免费视频| 视频一区二区三区免费观看| 久久久久一级精品亚洲国产成人综合AV区 | 日韩电影免费在线观看网址| 亚洲中文无韩国r级电影| 亚洲人成www在线播放| 热久久精品免费视频| 亚洲成aⅴ人片在线影院八| 波多野结衣在线免费视频| 亚洲日韩精品无码专区加勒比☆ | 99re这里有免费视频精品| ass亚洲**毛茸茸pics| 无码国模国产在线观看免费| 污视频网站在线观看免费| 亚洲精品国产精品乱码不99 | 亚洲好看的理论片电影| 中文字幕无码成人免费视频| 亚洲av日韩精品久久久久久a| 久久久久亚洲av成人无码电影| 久久永久免费人妻精品下载| 亚洲欧洲国产综合AV无码久久 | 久久久久久国产精品免费免费| 美女无遮挡免费视频网站| 国产成A人亚洲精V品无码|