目录
前言
解决方案一 编写脚本清空缓存
解决方案二 手动清空ByteBuf
总结
前言
公司的核心业务是由netty4处理的,存在虚拟内存不断飙升的问题。直接表现为netty服务运行几天后会自己宕机,持续观察线上情况,最后得出两个解决方案。
解决方案一 编写脚本清空缓存
好处是
- 见效快,脚本有现成,只需要复制一份,执行以下就可以清空;
- 通用性强,可以用来作为临时维护手段,适用多种情况;
- 不需要改代码,尤其源代码看着就头大,想改也无从下手;
- 比重启项目的方式好
坏处:
- 治标不治本,本身并没有解决问题,只是绕过了问题;
- 这种情况方式会影响netty正在处理的ByteBuf,会影响到业务;
#!/usr/bin/env bash#清理系统缓存
clearSystemCache(){echo ">>>>>>>>>>>>>>>>>>>>>>开始执行清除" $EVN "系统环境环境缓存<<<<<<<<<<<<<<<<<<<<<<<<<<<"#drop_caches的值可以是0-3之间的数字,代表不同的含义:
#0:不释放(系统默认值)
#1:释放页缓存
#2:释放dentries和inodes
#3:释放所有缓存#释放内存前先使用sync命令做同步,以保证文件系统的完整性,将所有未写的系统缓冲区写到磁盘中
#包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
echo ">>>>>>>>>>>>>>>>>>>>>>执行清理文件系统缓存和无用对象和它们占用的内存<<<<<<<<<<<<<<<<<<<<<<<<<<<"
sync#清理pagecache(页面缓存)
echo ">>>>>>>>>>>>>>>>>>>>>>执行清理pagecache(页面缓存)<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo 1 > /proc/sys/vm/drop_caches#清理dentries(目录缓存)和inodes
echo ">>>>>>>>>>>>>>>>>>>>>>执行清理dentries(目录缓存)和inodes<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo 2 > /proc/sys/vm/drop_caches#清理pagecache、dentries和inodes
echo ">>>>>>>>>>>>>>>>>>>>>>执行清理pagecache、dentries和inodes<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo 3 > /proc/sys/vm/drop_caches
}clearSystemCache
解决方案二 手动清空ByteBuf
参考如下链接:
- https://www.cnblogs.com/chyu/p/5212528.html (这个大佬提供一个解决思路)
- https://zhuanlan.zhihu.com/p/84141912 (这个大佬讲了一下netty监控内存泄露机制的源码)
在研究了一番之后,我们得知ByteBuf是通过计数保持存活状态的,netty本身会自动回收。查看了源代码之后,发现ByteBuf只作用于编解码接口和几个接受数据的对象,然后我们就在对象内部进行手动释放。最后线上问题得到了解决。(警告:不要释放继承框架中的byteBuf,会导致通道失效!!!)
ByteBuf byteBuf = Unpooled.buffer(9);
/**
业务处理
*/
byteBuf.release();
总结
作为一个贪婪的成年人,我全都要!在解决之前,查看了大佬们各种深入解决方案和内存排查手段。但是实际情况,内存泄露的情况并不是十分明显,所以有充足的时间进行测试。推荐大家可以利用htop监控,hcache查看缓存,使用arthas排查。