填坑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文件基本就找到问题根源了。

原文地址:https://www.cnblogs.com/render-inside/p/9015891.html

时间: 2024-08-29 18:19:07

填坑netty io.netty.util.internal.OutOfDirectMemoryError的相关文章

netty io.netty.buffer简介

io.netty.util.ReferenceCounted 此接口代表一个引用计数的对象,此对象需要显示的释放. 当一个ReferenceCounted对象被实例化的时候,该对象的引用数量就是1,调用retain()方法会增加引用数量,调用 release() 方法会减少引用数量,如果引用数量减少到0,该对象就需要显示释放掉.访问释放掉的对象通常会导致访问冲突. 如果实现ReferenceCounted接口的对象是一个包含同样实现ReferenceCounted接口的对象的容器.当容器的引用数

netty io.netty.channel介绍2

Interface ChannelHandlerContext 上下文对象使得当前channelhandler可以与其所属的channelpipeline以及其他handler进行交互,可以通知所属channelpipeline中的下一个handler,也可动态修改其所属的channelpipeline,具体功能如下: 通知.通过调用channelhandlercontext提供的方法可以调用同一个channelpipeline中的相邻的下一个channelhandler,详情可以参照chann

netty io.netty.channel 简介1

Interface AddressedEnvelope<M,A extends SocketAddress> 此接口将一个消息.发送地址和接收地址封装到了一起 Interface Channel 此接口表示到网络socket或者组件(component)的一个连接,其提供了IO操作的一些功能,比如read, write, connect, and bind.一个channel可以给用户提供如下功能:1.当前channel的状态(open.connected等).2.channel的配置参数(如

记一次netty版本冲突,报java.lang.NoSuchMethodError: io.netty.util.internal.ObjectUtil.checkPositive的问题

elasticsearch 5.6中使用TransportClient初始化抛异常 在引入elasticsearch5.6的transportclient包中,会引入netty进行通信. <!-- transport客户端 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version

Java io.netty.util.ReferenceCountUtil 代码实例

原文:https://www.helplib.com/Java_API_Classes/article_64580 以下是展示如何使用io.netty.util.ReferenceCountUtil的最佳示例. 我们使用了代码质量辨别算法从开源项目中提取出了最佳的优秀示例. 实例 1 复制代码 private static void testPerformOpeningHandshake0(boolean subProtocol) { EmbeddedChannel ch = new Embed

io.netty.resolver.dns.DnsNameResolverContext

java.net.UnknownHostException: failed to resolve 'xxx.com' after 3 queries at io.netty.resolver.dns.DnsNameResolverContext.finishResolve(DnsNameResolverContext.java:699) at io.netty.resolver.dns.DnsNameResolverContext.tryToFinishResolve(DnsNameResolv

Node学习笔记(四):gulp+express+io.socket部署angularJs2(填坑篇)

这篇就先暂停下上篇博客--你画我猜的进度,因为在做这个游戏的时候,想采用最新的ng2技术,奈何坑是一片又一片,这边就先介绍下环境部署和填坑史 既然要用ng2,首先要拿到资源,我这边用的是angularJs2 beta版的,网上的资源有两种,一个是文件全压缩版的.min.js版的另一个就是一大堆乱七八糟的js文件,主要是ng2已经完全采用TypeScript,加之对es6的支持,所以需要引入一大堆兼容,编译文件 这边刚好特别手欠想学学gulp,于是开搞配置gulp环境,压缩所有的js文件成一个mi

netty报错:io.netty.channel.ChannelPipelineException

1.九月 23, 2018 8:35:02 下午 io.netty.channel.ChannelInitializer channelRegistered警告: Failed to initialize a channel. Closing: [id: 0xa09c718b, /127.0.0.1:50509 => /127.0.0.1:9999]io.netty.channel.ChannelPipelineException: com.sxt.netty.first.Server4Hell

Netty学习——Netty和Protobuf的整合(一)

Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执行一下protoc 异常捕获:启动服务器端正常,在启动客户端的时候,发送消息,报错 警告: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the l