文章标题

java自带垃圾回收,因此内存泄漏是很隐蔽的,主要原因是对一个对象的引用被无意识的保留下来,垃圾回收机制不仅不会处理这个对象,也不会处理被这个对象所引用的所有其他对象。————今天重看effective java时,对《创建和销毁对象》这章有了更进一步的理解,现梳理一下=, =

1.过期引用,书中的例子

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];
}

private void ensureCapacity(){
    if(elements.length ==size)
        elements = Arrays.copyOf(elements, 2*size +1);
    }
}
“当这个栈先push再pop时,从栈中弹出的对象不会被当作垃圾回收”
PS:栈是限制插入和删除只能在一个位置上进行的表(即表的末端,称作栈顶,先进先出);

假设现在对一个Object e 进行push,element[4]=e,再进行pop弹出之前栈顶元素element[4],此时代码中直接return element[3]
即将下一个数组元素弹到栈顶,可以将栈理解为一根弹簧,上面最开始压着4块搬砖,后来又在最上面加了一块,再后来又搬走了新加的那块。那么问题来了,弹出的那块搬砖没人告诉我可以放下,于是我得一直用手拿着。个人脑洞大开的粗暴解释= =。
所以在return element[3]之前得先把element[4]=null;清空引用,告诉搬砖的我手可以放下这块砖了,于是GC才开始工作。
这种情况在我看来是可能性比较大的,编码过程中要注意一下。

2.将对象引用放到缓存中
在实际项目中,比如现在要判断从数据库查出的数据中是否含有Null值(返回DO对象)这个时候我会把对象放入一个hashmap中,迭代,遇到某值为Null的情况,返回该Null对应的对象。
这个应该符合把对象引用放到缓存中的情况,而且是很容易忘记清理引用。
书中给出的解决方案是使用WeakHashMap代表缓存,–使用弱引用,当缓存中的项过期后会自动删除。

“只有当所要的缓存项的生命周期是由该键的外部引用而不是由值决定时,weakhashmap才有用”--这句话没能理解
还有一种方法是由一个后台线程来进行清除工作,或者在给缓存添加新条目时顺便进行清理,LinkedHashMap通过removeEldestEntry方法很容易实现该方案。
对于更加复杂的缓存,必须直接使用java.lang.ref,这个包我还从来没用过,应该去看一下它的API的。

3.监听器和回调
这种情况是从来没听说过,更别说项目中写过了,这个场景我都有点想不出来:
如果你实现了一个API,客户端在这个API中注册回调,却木有显示地取消注册。确保回调立即被当作垃圾回收的最佳方法是只保存它的弱引用:保存为WeakHashMap中的键。

—-以上,对这部分第三点还缺乏认识,如有大神看到,还望不吝赐教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值