Netty学习之旅----源码分析Netty内存泄漏检测,2024年最新JAVA程序设计报告

2、Netty 直接内存的使用示例

=================

ByteBuf buf = Unpooled.directBuffer(512);

System.out.println(buf);

// SimpleLeakAwareByteBuf(UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 512))

// SimpleLeakAwareByteBuf是包装类,使用了装饰模式,内部维护一个UnpooledUnsafeDirectByteBuf,

// 该类与UnpooledDirectByteBuf类似。首先在创建SimpleLeakAwareByteBuf的时候,会将该引用加入到内存泄漏检测

// 的引用链中。

try {

//使用业务

} finally {

buf.release();//该方法首先调用直接内存UnpooledDirectByteBuf方法,释放所占用的堆外内存,

//然后调用leak.close方法,通知内存泄漏检测程序,该引用所指向的堆外内存已经释放,没有泄漏。

//如果 release没有调用,则当UnpooledDirectBytebuf被垃圾回收器收集号,该ByteBuf

//申请的堆外内存将再也不受应用程序所掌控了,会引起内存泄漏。

/*

  • public boolean release() {

boolean deallocated = super.release();

if (deallocated) {

leak.close();

}

return deallocated;

}

*/

}

3、Netty内存检测实现原理

===============

首先,Netty 的直接内存 ByteBuf 的数据结构:ByteBuf 对象内部维护一个 java.nio.ByteBuffer 的堆外内存。java.nio.ByteBuffer所占用的实际内存,JVM 虚拟机无法直接干预,JVM虚拟机GC只能回收 ByteBuf 对象本身,而无法回收 ByteBuf 所指向的堆外内存。

Netty封装基本的堆外内存是用 UnpooledDirectByteBuf 对象,Netty 在每次创建一个 UnpooledDirectByteBuf 时,为了能够追踪到 UnpooledDirectByteBuf 的垃圾回收,需要将该对象用一个虚拟引用指向它,将其注册到一条引用链中。然后需要将该引用对象与 ByteBuf 对象保存起来,所以 Netty 使用装饰模式,利用一个包装类 SimpleLeakAwareByteBuf 对象,将原 ByteBuf 包装一下,但对外表现的特性,就是一个ByteBuf,我们来看一下:

4、io.netty.util.ResourceLeakDetector 源码分析

=========================================

4.1 内部结构详解


4.1.1 内存检测级别

/**

  • Represents the level of resource leak detection.

*/

public enum Level {

/**

  • Disables resource leak detection.

*/

DISABLED,

/**

  • Enables simplistic sampling resource leak detection which reports there is a leak or not,

  • at the cost of small overhead (default).

*/

SIMPLE,

/**

  • Enables advanced sampling resource leak detection which reports where the leaked object was accessed

  • recently at the cost of high overhead.

*/

ADVANCED,

/**

  • Enables paranoid resource leak detection which reports where the leaked object was accessed recently,

  • at the cost of the highest possible overhead (for testing purposes only).

*/

PARANOID

}

  • DISABLED : 禁用内存泄露检测

  • SIMPLE:默认的内存检测级别,以一个时间间隔,默认是每创建113个直接内存(堆外内存)时检测一次。

  • ADVANCED与PARANOID 每次产生一个堆外内存,目前这两个在Netty的实现中等价,统一用ADVANCED来实现。

4.1.2 内部属性

/** the linked list of active resources */

private final DefaultResourceLeak head = new DefaultResourceLeak(null);

private final DefaultResourceLeak tail = new DefaultResourceLeak(null);

private final ReferenceQueue refQueue = new ReferenceQueue();

private final ConcurrentMap<String, Boolean> reportedLeaks = PlatformDependent.newConcurrentHashMap();

private final String resourceType;

private final int samplingInterval;

private final long maxActive;

private long active;

private final AtomicBoolean loggedTooManyActive = new AtomicBoolean();

private long leakCheckCnt;

  • ResourceLeakDetector

内部维护一个双端链表,维护所有指向堆外内存的引用对象链(ResourceLeak对象链,ResourceLeak的实现类,继承虚拟引用PhantomReference),head 与 tail 是虚拟节点。

  • refQueue

引用队列,该引用队列正存放的是 ResoureLeak 对象链,代表着这里面的引用对象所指向的对象已被垃圾回收。按照常理,如果该 ResourceLeak 对象,也同时存在于上面的双端链表中,说明发生了内存泄漏。

  • resourceType

检测对象的完全限定名称,主要用途用于报告内存泄漏时,相关的详细信息。

  • samplingInterval

内存泄漏检测级别是SIMPLE时,的检测频率,默认113,单位为个,而不是时间。

  • maxActive

该类对象的最大激活数量。

  • active

当前激活的数量。

  • loggedTooManyActive

active * samplingInterval > maxActive 条件满足时,是否打印日志。

4.2.1 ResourceLeakDetector open 方法详解

AbstractByteBufAllocator 的 toLeakAwareBuffer 入口,然后进入到 ResourceLeakDetector open方法。

protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) {

ResourceLeak leak;

switch (ResourceLeakDetector.getLevel()) {

case SIMPLE:

leak = AbstractByteBuf.leakDetector.open(buf);

if (leak != null) {

buf = new SimpleLeakAwareByteBuf(buf, leak);

}

break;

case ADVANCED:

case PARANOID:

leak = AbstractByteBuf.leakDetector.open(buf);

if (leak != null) {

buf = new AdvancedLeakAwareByteBuf(buf, leak);

}

break;

}

return buf;

}

该方法的意思是如果返回一个 ResoureLeak,则用 ResourceLeak 与当前的 ByteBuf 放入一个包装类,跟踪该直接内存的回收情况,检测内存泄露。如果没有产生一个 ResourceLeak,则不会跟踪直接内存的泄露检测。

/**

  • Creates a new {@link ResourceLeak} which is expected to be closed via {@link ResourceLeak#close()} when the

  • related resource is deallocated.

  • @return the {@link ResourceLeak} or {@code null}

*/

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数同学面临毕业设计项目选题时,很多人都会感到无从下手,尤其是对于计算机专业的学生来说,选择一个合适的题目尤为重要。因为毕业设计不仅是我们在大学四年学习的一个总结,更是展示自己能力的重要机会。

因此收集整理了一份《2024年计算机毕业设计项目大全》,初衷也很简单,就是希望能够帮助提高效率,同时减轻大家的负担。
img
img
img

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
img

。**
[外链图片转存中…(img-Fj5xKFRQ-1712529307999)]
[外链图片转存中…(img-cS6USO2a-1712529307999)]
[外链图片转存中…(img-dHMOEAIo-1712529308000)]

既有Java、Web、PHP、也有C、小程序、Python等项目供你选择,真正体系化!

由于项目比较多,这里只是将部分目录截图出来,每个节点里面都包含素材文档、项目源码、讲解视频

如果你觉得这些内容对你有帮助,可以添加VX:vip1024c (备注项目大全获取)
[外链图片转存中…(img-JV9NCqXi-1712529308000)]

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值