记生产一次弱引用对象引起的空指针异常

WeakReference如字面意思,弱引用, 当一个对象仅仅被weak reference(弱引用)指向, 而没有任何其他strong reference(强引用)指向的时候, 如果这时GC运行, 那么这个对象就会被回收,不论当前的内存空间是否足够,这个对象都会被回收。
作者:BrightLoong
链接:https://www.jianshu.com/p/964fbc30151a

使用背景:
弱引用对象常用于对象在内存中生命周期短,且占空间,在本次异常发生的对象是公司封装的HttpRequest弱引用对象

public HttpRequest getRequest() {
        return (HttpRequest)this.httpRequestRef.get();
    }
private WeakReference<HttpRequest> httpRequestRef

在业务逻辑中需要根据请求参数操作不同的分库,所以在Request对象中setAttribute有具体的分库index
然后在接口请求时启动另外一个线程执行任务,在线程中获取Request对象设置分库index

getRequestContext().setVaule(contextKey, value);

然后错误发生了,由于Request是弱引用对象,在另起线程时,如果发生GC,(HttpRequest)this.httpRequestRef.get();就会报空指针异常,由于在测试环境没有发生GC,导致这个BUG上到生产环境,百度一圈,然后再测试环境任务线程启动马上手动System.gc(),果然100%复现。
解决方法:
然后,在任务线程中传入Request对象,在线程中用强引用它,GC的时候就不会回收,空指针问题解决,但是会出现新问题,由于是线程池管理的线程,任务结束后,线程并没有结束,所以Request仍然不会被回收,可能会导致内存泄露,所以最后再释放一下对象就OK

public void clearCurrentRequestContext() {
        contextHolder.remove();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值