Netty ByteBuf泄露定位修改。
1. ByteBuf
2. 问题描述
日志记录中报堆外内存溢出。
3. 问题定位及修改
Netty提供了ByteBuf泄露的检测机制。
JVM启动参数中添加: -Dio.netty.leakDetectionLevel=advanced , log4j2.xml配置io.netty日志记录即可。
禁用(DISABLED) – 完全禁止泄露检测,省点消耗。
简单(SIMPLE) – 默认等级,告诉我们取样的1%的ByteBuf是否发生了泄露,但总共一次只打印一次,看不到就没有了。
高级(ADVANCED) – 告诉我们取样的1%的ByteBuf发生泄露的地方。每种类型的泄漏(创建的地方与访问路径一致)只打印一次。对性能有影响。
偏执(PARANOID) – 跟高级选项类似,但此选项检测所有ByteBuf,而不仅仅是取样的那1%。对性能有绝大的影响。
检测到如下泄露点,
举例1:
13:29:25.273 [MODBUS_MESSAGE_POOL-thread-14] [] [] [] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Created at:
io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:604)
io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:849)
com.pinnet.protocol.hwmodbus.message.ModbusMessageRunnable.run(ModbusMessageRunnable.java:46)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
可以看到readBytes()创建后,没有释放。
修改:
buffer.readBytes(4).release();
举例2:
2018-06-30 13:29:25.278 [MESSAGE_POOL-thread-14] [] [] [] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
#1:
io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:273)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1380)
io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1159)
io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1194)
io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
#2:
io.netty.buffer.AdvancedLeakAwareByteBuf.getUnsignedShort(AdvancedLeakAwareByteBuf.java:172)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.getUnadjustedFrameLength(LengthFieldBasedFrameDecoder.java:469)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:417)
com.pinnet.protocol.hwmodbus.tcp.MobusLengthDecoder.decode(MobusLengthDecoder.java:32)
#3:
io.netty.buffer.AdvancedLeakAwareByteBuf.order(AdvancedLeakAwareByteBuf.java:70)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.getUnadjustedFrameLength(LengthFieldBasedFrameDecoder.java:462)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:417)
com.pinnet.protocol.hwmodbus.tcp.MobusLengthDecoder.decode(MobusLengthDecoder.java:32)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)
io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
#4:
Hint: 'decoder' will handle the message from this point.
#5:
Hint: 'idleHandler' will handle the message from this point.
修改:解码器中释放Bytebuf in
public class MobusLengthDecoder extends LengthFieldBasedFrameDecoder {
public MobusLengthDecoder(ByteOrder byteOrder, int maxFrameLength,
int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment,
int initialBytesToStrip, boolean failFast) {
super(byteOrder, maxFrameLength, lengthFieldOffset, lengthFieldLength,
lengthAdjustment, initialBytesToStrip, failFast);
}
@Override
protected Object decode(ChannelHandlerContext ctx,
io.netty.buffer.ByteBuf in) throws Exception {
ByteBuf buf = (ByteBuf) super.decode(ctx, in);
// LEAK: ByteBuf.release() was not called before it's garbage-collected.
in.release();
...
}
}
Netty ByteBuf泄露定位修改。的更多相关文章
- 对于 Netty ByteBuf 的零拷贝(Zero Copy) 的理解
此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: "Zero-copy" describes computer opera ...
- 双11线上压测netty内存泄露
最近线上压测,机器学习模型第一次应用到线上经历双11大促.JSF微服务有报错 LEAK: ByteBuf.release() was not called before it's garbage-co ...
- Netty ByteBuf(图解之 2)| 秒懂
目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...
- IOS免越狱虚拟定位修改工具共享 Jocation
Jocation IOS虚拟定位修改器 具体使用方法可以按照 location cleaned软件相同的操作. 主要是因为本人有一部 IphoneX 和Iphone Xs Max 网上的locatio ...
- netty byteBuf (二)
netty重新定义了byteBuf 而没使用jdk byteBuffer netty byteBuf与jdk byteBuffer的区别 (1)jdk buffer长度固定 byteBuf超过最大 ...
- 从一次netty 内存泄露问题来看netty对POST请求的解析
背景 最近生产环境一个基于 netty 的网关服务频繁 full gc 观察内存占用,并把时间维度拉的比较长,可以看到可用内存有明显的下降趋势 出现这种情况,按往常的经验,多半是内存泄露了 问题定位 ...
- Netty ByteBuf源码分析
Netty的ByteBuf是JDK中ByteBuffer的升级版,提供了NIO buffer和byte数组的抽象视图. ByteBuf的主要类集成关系: (图片来自Netty权威指南,图中有一个画错的 ...
- netty ByteBuf分析
1.Heap Buffer(堆缓冲区) 2.Direct Buffer(直接缓冲区) 3.Composite Buffer(复合缓冲区) 4.PooledByteBuf 池缓冲 readerInex ...
- Netty ByteBuf梳理
我们知道,网络数据的基本单位总是字节.Java NIO提供了ByteBuffer作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐. Netty的ByteBuffer替代品是ByteBuf, ...
随机推荐
- iOS进阶二-KVC
概述 KVC的全程是Key-Value Coding, 俗称"键值编码",可以通过一个key来访问属性 常见的AP有 - (void)setValue:(nullable id)v ...
- 2018-10-29-微软-Tech-Summit-技术暨生态大会课程-·-基于-Roslyn-打造高性能预编译框架...
title author date CreateTime categories 微软 Tech Summit 技术暨生态大会课程 · 基于 Roslyn 打造高性能预编译框架 lindexi 2018 ...
- Python学习笔记(三)——文件系统中的常用方法
OS模块中关于文件/目录常用的函数使用方法 函数名 使用方法 getcwd() 返回当前工作目录 chdir() 改变工作目录 listdir(path='.') 列举指定目录中的文件名('.'表示当 ...
- Android系统开发 编译系统签名的APP
前言 一般情况下,我们使用的签名都是自己生成的Java签名来编译APP. 但是,如果需要开发一些特定设备的APP(对权限有更高的要求,需求一些系统基本的权限,比如让APP可以控制设备的休眠),那就需要 ...
- CSIC_716_20191126【面向对象编程--继承】
继承 什么是继承:继承是新建类的一种方式,通过此方式生成的类称为子类.或者 派生类,被继承的类称为父类.基类或超类.在python中,一个子类可以继承多个父类. 继承的作用:减少代码的冗余,提高开发效 ...
- centos 下载并安装nodejs
安装方法1——直接部署 1.首先安装wget ,这个一般都有自带有的,可能已经在系统里安装好了的. yum install -y wget 如果已经安装了可以跳过该步 2.下载nodejs最新的tar ...
- java基本类型映射表
- js面试总结3
异步和单线程 题目: 1.同步和异步的区别? 2.一个关于setTimeout的笔试题. 3.前段使用异步的场景有哪些? 什么是异步? console.log(100) setTimeout(func ...
- 三模数NTT模板
求两个多项式的卷积对任意数p取模 两个好记的FNT模数: 5*2^25+1 7*2^26+1 原根都为3 //Achen #include<algorithm> #include<i ...
- ps快速将白底图片变为透明图片
方法一: 如果图层有锁图标,则要点击它,然它消失.然后选中魔棒工具,然后点击图片上要透明的区域,按下backspace键即可. 方法二: 转载自:https://blog.csdn.net/sunyi ...