消除过期的对象引用
2017-03-12 08:31 ttylinux 阅读(721) 评论(0) 编辑 收藏 举报import java.util.Arrays; import java.util.EmptyStackException; public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { 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) { elements = Arrays.copyOf(elements, 2 * size + 1); } } }
public Object pop() { if (size == 0) throw new EmptyStackException(); Object result = elements[--size]; elements[size] = null; return result; }
public class SocketManager { private Map<Socket,User> m = new WeakHashMap<Socket,User>(); public void setUser(Socket s, User u) { m.put(s, u); } public User getUser(Socket s) { return m.get(s); } }
上述代码,当外部代码没有持有m中的一个键的引用,那么,该WeakHashMap就会键该键移除掉。不用我们手工去移除。(Hash table based implementation of the Map interface, with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.)
"WeakHashMap
用弱引用承载映射键,这使得应用程序不再使用键对象时它们可以被垃圾收集,get()
实现可以根据 WeakReference.get()
是否返回 null
来区分死的映射和活的映射。但是这只是防止 Map
的内存消耗在应用程序的生命周期中不断增加所需要做的工作的一半,还需要做一些工作以便在键对象被收集后从 Map
中删除死项。否则,Map
会充满对应于死键的项。虽然这对于应用程序是不可见的,但是它仍然会造成应用程序耗尽内存,因为即使键被收集了,Map.Entry
和值对象也不会被收集。
Map
,对每一个弱引用调用 get()
,并在 get() 返回 null
时删除那个映射而消除死映射。但是如果 Map
有许多活的项,那么这种方法的效率很低。如果有一种方法可以在弱引用的 referent 被垃圾收集时发出通知就好了,这就是引用队列 的作用。BlockingQueue
同样的出列模式 —— polled、timed blocking 和 untimed blocking。)”WeakHashMap
有一个名为 expungeStaleEntries()
的私有方法,大多数 Map
操作中会调用它,它去掉引用队列中所有失效的引用,并删除关联的映射。清单 7 展示了 expungeStaleEntries()
的一种可能实现。用于存储键-值映射的 Entry
类型扩展了 WeakReference
,因此当expungeStaleEntries()
要求下一个失效的弱引用时,它得到一个 Entry
。用引用队列代替定期扫描内容的方法来清理 Map
更有效,因为清理过程不会触及活的项,只有在有实际加入队列的引用时它才工作。"清单 7. WeakHashMap.expungeStaleEntries() 的可能实现 private void expungeStaleEntries() { Entry<K,V> e; while ( (e = (Entry<K,V>) queue.poll()) != null) { int hash = e.hash; Entry<K,V> prev = getChain(hash); Entry<K,V> cur = prev; while (cur != null) { Entry<K,V> next = cur.next; if (cur == e) { if (prev == e) setChain(hash, next); else prev.next = next; break; } prev = cur; cur = next; } } }
3.监听器和回调
public class MainActivity extends AppCompatActivity implements OnNetworkChangedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NetworkManager.getInstance().registerListener(this); } @Override public void onNetworkUp() { } @Override public void onNetworkDown() { } }
public class MainActivity extends AppCompatActivity implements OnNetworkChangedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NetworkManager.getInstance().registerListener(this); } @Override public void onNetworkUp() { } @Override public void onNetworkDown() { } @Override protected void onDestroy() { super.onDestroy(); NetworkManager.getInstance().unregisterListener(this); } }
引用: