清理过期的对象引用
概述
在使用具备垃圾自动回收功能的编程语言时,可能会对不需要手动管理内存感到不可思议,以为不再需要考虑内存管理的事情。其实不然
例子
如果一个程序使用栈的时候先增长,后收缩,那么弹出来的对象将不会被当作垃圾回收,这是栈对对象的过期引用,虽然下标已经发生了改变,但对象应用却被无意识地保留了起来。
要解决这个问题,可以清空这些引用即可:
1 | public Object pop() { |
这样做还有一个好处,一旦被错误地引用,会抛出NullPointerException。
注意
- 清空对象引用应该是一种例外,而不是一种规范行为;
- 只要类是自己管理内存的,程序员应该警惕内存泄漏问题
内存泄漏来源
- 缓存
如果对象引用被放到缓存中,很可能被遗忘掉,以至于很长一段时间内都留在缓存中;
比如好的解决方法是用WeakHashMap代表缓存,但只有当所要的缓存项的生命周期是由key的外部引用而不是value决定时,才有用。tomcat的源码里,实现缓存时会用到WeakHashMap
- 监听器和其他回调
客户端在Api中注册了回调,却没有显式地取消回调。那么这时最好的解决方法是,将它们保存为WeakHashMap的key,即保存它们的弱引用。