netty之ResourceLeakDetector的使用与实现

通过WeakReference和ReferenceQueue做针对需要手动释放的资源的侦测

使用

  1. 设置日志级别:
ServerBootstrap b =new ServerBootstrap();
b.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 2048)
.handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(new ChildChannelHandler()); 2017-01-19 10:04:49 [ nioEventLoopGroup-1-0:1628830 ] - [ ERROR ] LEAK: ByteBuf.release() was not called before it's garbage-coll...
  1. ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);或者通过JVM参数配置

    日志:
2017-01-19 10:35:59  [ nioEventLoopGroup-1-0:665092 ] - [ ERROR ]  LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 5
#5:
io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:435)

分析

[ ERROR ] LEAK:

// ResourceLeakDetector
protected void reportTracedLeak(String resourceType, String records) {
logger.error(
"LEAK: {}.release() was not called before it's garbage-collected. " +
"See http://netty.io/wiki/reference-counted-objects.html for more information.{}",
resourceType, records);
} private void reportLeak() {
if (!logger.isErrorEnabled()) {
clearRefQueue();
return;
} // Detect and report previous leaks.
for (;;) {
@SuppressWarnings("unchecked")
DefaultResourceLeak ref = (DefaultResourceLeak) refQueue.poll(); // 为什么能拿到?什么时候 放进去的?是weakreference回收过程中放进去的,相当于GC过程让你插入hook。那为什么被GC了还有资源泄露呢?这个问题其实是这样的,泄露是池化内存等那些需要手动释放资源。
if (ref == null) {
break;
} if (!ref.dispose()) { // return allLeaks.remove(this); 所以当有人显式释放过,那么此处就返回false 就不会往下走report了
continue;
} String records = ref.toString();
if (reportedLeaks.putIfAbsent(records, Boolean.TRUE) == null) {
if (records.isEmpty()) {
reportUntracedLeak(resourceType);
} else {
reportTracedLeak(resourceType, records);
}
}
}
}

基本实现原理是:

  1. 通过DefaultResourceLeak继承自WeakReference,借助WeakReference的GC特性完成。WeakReference的GC特性是当这个对象没有被其他强引用对象引用时,仅仅被WeakReference引用(或者其他weak引用)时,会在下一次GC时回收,回收过程中会将被回收的引用放到ReferenceQueue中。此处的ReferenceQueue又是在创建DefaultResourceLeak时通过构造参数传入的。
  2. 不时poll那个ReferenceQueue队列,当拿到对象时看起dispose是否被调用过,如果没有则证明没有显示释放,则report出来。
  3. 每次创建池化buf对象时,便会创建DefaultResourceLeak,并在touch等API中调用其record方法,追踪其申请使用的地方。在开启了泄露追踪后,buf会被包装,比如包装成AdvancedLeakAwareByteBuf。
  4. 侦测reportLeak不是每次都调用,当小雨PARANOID级别是在申请buf时按随机数比例调。PARANOID级别是全调。

此处资源泄露,是指那种需要手动释放的资源,因为引用他的对象已经不在程序逻辑中使用了,那么最终会被GC回收,但是那种需要手动释放的资源不显式释放就泄露了。比如内存池,比方说里面有5个杯子,你用的buf指向一个杯子被你占着,你不用时没显式告诉内存池说这个杯子不用了,那么就一直占着,但是buf对象不用了会被GC回收,那么此时内存池资源就泄露了。

[netty4][netty-common]netty之ResourceLeakDetector的使用与实现的更多相关文章

  1. 【Netty】Netty入门之WebSocket小例子

    服务端: 引入Netty依赖 <!-- netty --> <dependency> <groupId>io.netty</groupId> <a ...

  2. Netty学习——Netty和Protobuf的整合(二)

    Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...

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

    Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...

  4. 【netty】Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  5. 【Netty】Netty核心组件介绍

    一.前言 前篇博文体验了Netty的第一个示例,下面接着学习Netty的组件和其设计. 二.核心组件 2.1. Channel.EventLoop和ChannelFuture Netty中的核心组件包 ...

  6. 【Netty】Netty传输

    一.前言 在简单学习了Netty中的组件后,接着学习Netty中数据的传输细节. 二.传输 2.1 传输示例 Netty中的数据传输都是使用的字节类型,下面通过一个实例进行说明,该实例中服务器接受请求 ...

  7. 【Netty】Netty之ByteBuf

    一.前言 前面已经学习了Netty中传输部分,现在接着学习Netty中的ByteBuf. 二.ByteBuf 2.1 ByteBuf API 在网络上传输的数据形式为Byte,Java NIO提供了B ...

  8. 【Netty】Netty之Bootstrapping

    一.前言 前面已经学习了Netty的EventLoop以及线程模型,接着学习Netty的Bootstrapping. 二.Bootstrapping 在学习了Netty中的很多组件后,如何将这些组件有 ...

  9. netty学习--netty源码中的部分util方法

    io.netty.buffer.AbstractByteBuf#calculateNewCapacity  申请内存空间 private int calculateNewCapacity(int mi ...

  10. Netty 之 Netty生产级的心跳和重连机制

    https://blog.csdn.net/z69183787/article/details/52625095 最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github ...

随机推荐

  1. 通过cmd进入指定D盘下的某个文件夹

    有时候我们在使用电脑的时候,想使用cmd命令提示符,进入d盘,怎么操作呢,下面来分享一下方法 案例描述:如果进入D盘下的test文件夹(D:\test) 1.win10系统环境下,点击搜索输入[cmd ...

  2. 商品表(spu)、规格表(sku)设计

    1. 先做一下专业术语解释:spu和sku 这里拿iphone6s举例,它身上有很多的属性和值, 比如: 毛重: 420.00 g 产地: 中国大陆 容量: 16G, 64G, 128G 颜色: 银, ...

  3. 虚拟化-SDDC软件定义数据中心

    一.什么是SDDC? SDDC依赖于虚拟化和云计算技术, SDDC的目标是虚拟化数据中心的一切物理资源,通过虚拟化的技术,构建一个由虚拟资源组成的资源池,不仅是对服务器进行虚拟化,还包括存储虚拟化和网 ...

  4. thymeleaf js绑定多个变量参数

    写法一: <img th:src="@{/css/bianji.png}" th:onclick="|viewById('${user.id}','${user.i ...

  5. C#程序员装机必备软件及软件地址

    装机必备 Visio2010 下载 http://gd.ddooo.com/visio2010_12530.rar Office 安装包 http://xz.cncrk.com:8080/soft/k ...

  6. 前端学习(八):CSS

    进击のpython ***** 前端学习--CSS 现在的互联网前端分为三层: HTML:超文本标记语言.从语义的角度描述页面结构 CSS:层叠样式表.从审美的角度负责页面样式 JS:Javascri ...

  7. 2020想学习JAVA的同学看过来,最基础的编程CRUD你会了没?

    一 JDBC简介 Java DataBase Connectivity Java语言连接数据库 官方(Sun公司)定义的一套操作所有关系型数据库的规则(接口) 各个数据库厂商去实现这套接口 提供数据库 ...

  8. laravel开发调试工具laravel-debugbar的安装

    一.使用 Composer 安装该扩展包 composer require barryvdh/laravel-debugbar --dev 二.(可选)修改配置文件app/config.php Lar ...

  9. PHP linkinfo() 函数

    定义和用法 linkinfo() 函数返回有关一个硬连接的信息. 该函数返回设备 ID,如果失败则返回 FALSE. 语法 linkinfo(path) 参数 描述 path 必需.规定要检查的路径. ...

  10. C++模板沉思录(上)

    花下猫语: 在我们读者群里,最近出现了比较多关于 C++ 的讨论,还兴起了一股学习 C++ 的风气.樱雨楼小姐姐对 C++ 的模板深有研究,系统地梳理成了一篇近 4 万字的文章!本文是上篇,分享给大家 ...