百无聊赖篇之我与netty的第一次亲密接触-BrpcJava误用之堆外内存泄漏

服务在启动时总会出现这样的日志

但只会出现一次,而且报告内存泄漏的线程也不固定,由报告线程栈来看,不由得让人产生这样的疑问 “难道所有使用了netty的框架都有内存泄漏?”

由于对netty不了解, 那时的我是这样认为的(2020年前我其实没写过什么Java代码,更别提Netty啦)

  1. 内存泄漏日志只出现一次,那应该就只有一次内存泄漏,没什么影响

  2. 已经发现了内存泄漏,框架应该会把泄漏的内存回收掉,没什么影响

但事实确不是这样,随着服务的长时间运行最终会迎来堆外内存OOM(如果服务存在堆外内存泄漏,但一时半会又无法定位解决,还是不要设置-XX:MaxDirectMemorySize为好,让它触发oom killer挂掉重启或者捕获了OutOfMemory后异常退出服务触发重启,不然服务还是会正常接收请求,但返回数据为空,影响服务质量)



事实是什么?

为了看清事实,我们需要先了解一点netty检测内存泄漏的原理

对于使用netty的PooledByteBufAllocator分配出去的ByteBuf对象(下文皆指堆外内存),netty都会用一个DefaultResourceLeak的弱引用对象去跟踪,当ByteBuf对象被垃圾回收,DefaultResourceLeak对象就会被放到与之关联的引用队列中(DefaultResourceLeak对象创建时指定的队列),当有业务线程调用newDirectBuffer分配内存时就会调用reportLeak触发内存泄漏检查(这就是为什么内存泄漏时,报告线程不固定的原因),而且每个泄漏点只会报告一次(netty会把每次已经报告的泄漏点记录下来)



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值