zoukankan      html  css  js  c++  java
  • 填坑netty io.netty.util.internal.OutOfDirectMemoryError

    我们有个与外部交互的接口是采用netty http,具体版本netty-4.1.18,为什么使用这个版本,我也不知道,历史原因。

    由于netty都是异步请求,所以与外部交互总有些唯一的业务标识需要保存,以便前后数据可以勾兑。

    这里先说明下,netty里的ByteBuf在读取channelRead未进行写write操作时,需要自己释放release。这和本次Error关系不大,继续说重点。

    查看日志,首先发现了OutOfDirectMemoryError错误,这个错误也是间断性的出现,显然是内存不够用了,不管是heap还是direct。

    直接dump了一份堆内存日志,具体命令:jmap -dump:format=b,file=tomcat.dump pid。我们的服务是放在tomcat上的,jps一下,那个bootStrap就是。

    dump以后,找工具查看,推荐使用java自带的jvisualvm,在java目录的bin下,java自带的命令还是很好用的,比如上面提到的jps,jps -v比ps -ef |grep XXX 方便多了。

    装载dump文件后,如图所示:

    大概瞅一眼,某些类的实例也忒多了,满世界都是ConcurrentHashMap,绝壁有问题,这么造内存够用才怪,接着看到下面的netty有关的类实例,

    查看代码使用AttributeKey的地方,又看了源码实现,大概有些眉目,应该是对象创建过多,导致内存溢出了。

    每个实例下都挂这一个ConcurrentHashMap,不知道是不是我们的用法有问题,先不管了,先解决问题,

    发现代码每次请求都创建一个连接channel,每次都会全局保存一个AttributeKey,以便在请求异步响应时,勾兑原始数据,so,每天几百万请求就有点春困秋乏了,

    借用AttributeKey的思路,改为自己全局保存一个ConcurrentHashMap,然后键值对保存唯一业务标识,并且在异步处理之后remove过时数据。

    AttributeKey我翻了翻源码,真没看到在哪里可以释放的地方,有一个set(null)当然代码并没有使用过后设空操作,但是AttributeKey内部的haspMap不会自动释放。

    修改以后,重新部署。观察了几天,dump了新的内存日志,并没有发现过多的对象实例。继续观察一段时间。

    有关内存溢出的问题其实并没有想的那么困难,内存不够用自然会FullGC或者内存溢出,有些内存泄漏也会最终引发FullGC或内存溢出,找到过多的垃圾对象,

    该释放的释放,该单例的使用单例,能重用的尽量重用,应该没什么问题,看看dump文件基本就找到问题根源了。

  • 相关阅读:
    VSCode远程编写Shell并实时调试配置过程
    eclispe 无法启动调试 cannot connect to VM
    工作流之设置表访问权限
    利用工作流返回达到无限次重复办理业务的过程
    eworkflow工作流系统在iis中发布
    ie8用ajax访问不能每次都刷新的问题
    视频演示(动态指定执行人+指定申请人的上级)
    视频演示eworkflow集成定制aspx页面的过程
    利用开发框架中的标签库集成报表工具
    流程设计器之标签工具
  • 原文地址:https://www.cnblogs.com/render-inside/p/9015891.html
Copyright © 2011-2022 走看看