EJ.06古いオブジェクト参照を削除

1869 ワード

  • Java言語もメモリ管理
  • を考慮する必要がある
    //Can u spot the "memory leak"?
    public class Stack {
        private Ojbect[] elements;
        private int size = 0;
        private static final int DEFAULT_INITIAL_CAPACITY = 16;
        public Stack(int initialCapacity) {
            elements = new Object[DEFAULT_INITIAL_CAPACITY];
        }
        public void push(Object e) {
            ensureCapacity();
            elements[size++] = e;
        }
        public Object pop() {
            if (size == 0)
                throw new EmptyStackException();
            return elements[--size];
        }
        /**
         * Ensure space for at least one more element, roughly doubling the capacity
         * each time the array needs to grow.
         */
        private void ensureCapacity() {
            if (elements.length == size) {
                Object[] oldElements = elements;
                elements = Arrays.copyOf(elements, 2 * size + 1);
            }
        }
    }

    以上のコードはメモリオーバーフローのリスクがあります.スタックが先に成長してから収縮した場合、スタック内のpopで話されたオブジェクトはゴミとして回収されません.スタック内部では、これらのオブジェクトの期限切れ参照(obsolete reference)が維持されているためです.
      
  • オブジェクト参照が期限切れになると、これらの参照を空にするだけで
  • になります.
        public Object pop() {
            if (size == 0)
                throw new EmptyStackException();
            Object result = elements[--size];
            elements[size] = null;
            return result;
        }
  • 期限切れの参照を除去する最良の方法は、その参照を含む変数をそのライフサイクル
  • を終了させることである.
    遗留任务:学习EJ.45の場合、最もコンパクトな役割ドメイン範囲で各変数を定義すると、以上のシナリオが自然に発生します.
  • クラスが自己管理メモリである限り、メモリ漏洩問題
  • に警戒すべきである.
  • メモリ漏洩のもう一つの一般的なソースはキャッシュ(EJ p 23)
  • である.
  • メモリ漏洩の3番目の一般的なソースは、リスナーおよびその他のコールバック
  • です.
    残されたタスク:この文を確認し、Demoを書いて検証します.「コールバックが直ちにゴミ回収として扱われることを保証する最善の方法は、それらの弱い参照のみを保存することである」.