Netty为什么要手动释放ByteBuf资源?

简介: Netty为什么要手动释放ByteBuf资源?

ByteBuf是Netty网络通信框架中一个重要的组件。先进和友好的设计理念让开发者受益匪浅。


  1. 两个指针操作ByteBuf -> 读和写
  2. 对象池技术 -> 非垃圾回收机制


对象池技术1


3.对象池模式是一种软件创建设计模式,它使用一组可重用的对象 - “池” ,而不是按需分配和销毁它们。池的客户端从池中请求对象并对返回的对象执行操作。当客户端完成后,它将对象返回到池而不是销毁它,这可以手动或自动完成。

4.在某些情况下,对象池可显着提高性能。对象池使对象生存期复杂化,因为此时实际上并未创建或销毁从池中获取和返回到池的对象,因此需要小心实现。

5.常用在实例化开销大的对象。


Netty利用ByteBuf对象池2

BUFFER POOLING


6.Netty在对象池中利用引用计数器技术,为创建的ByteBuf对象设置引用计数器。

7.仅当引用计数器的值为0时,返回对象池回收。

8.新创建的引用计数对象的计数器的初始值为1:

ByteBuf buf = ctx.alloc().directBuffer();
assert buf.refCnt() == 1;

9.释放引用计数对象时,其引用计数器的值减1。如果引用计数到达0,则引用计数对象将被释放或返回其对象池:

assert buf.refCnt() == 1;
// release() returns true only if the reference count becomes 0.
boolean destroyed = buf.release();
assert destroyed;
assert buf.refCnt() == 0;

10.尝试访问引用计数器的值为0的引用计数对象将触发IllegalReferenceCountException异常:

assert buf.refCnt() == 0;
try {
  buf.writeLong(0xdeadbeef);
  throw new Error("should not reach here");
} catch (IllegalReferenceCountExeception e) {
  // Expected
}

11.谁来销毁引用计数对象


一般的经验法则是,最后访问引用计数对象的一方负责销毁引用计数对象。 进一步来说:

  • 如果[发送]组件应该将引用计数对象传递给另一个[接收]组件,则发送组件通常不需要销毁它,而是将该决定推迟到接收组件。
  • 如果组件使用引用计数对象并且知道其他任何内容都不再访问它(即,不传递给另一个组件引用),则组件应该销毁它。


为什么Netty会发生内存泄漏问题3


12.如果应用程序在使用ByteBuf后,没有调用方法release()(这个方法将其放回对象池中),又没有任何进一步的引用,则会发生泄漏。 在这种情况下,缓冲区最终将被GC(垃圾回收器)清除,但Netty的对象池不会知道这种情况。 然后,对象池将逐渐相信程序正在使用越来越多的永不返回池中的ByteBuf。这可能会产生内存泄漏。这可能会产生内存泄漏,因为ByteBuf被垃圾回收器回收,对象池回收不到它。导致对象池创建越来越多的新的引用计数对象。具体的Netty内部优化,请看Netty Internals - Optimizations everywhere


参考文献


https://en.wikipedia.org/wiki/Object_pool_pattern#Criticism ↩︎


https://netty.io/wiki/reference-counted-objects.html ↩︎


https://stackoverflow.com/questions/6697709/are-java-directbytebuffer-wrappers-garbage-collected ↩︎


相关文章
|
17小时前
|
Java API 容器
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf
88 0
|
8月前
|
Java API 开发者
Netty详解ByteBuf
Netty详解ByteBuf
48 0
|
17小时前
|
Java API 索引
Netty Review - ByteBuf 读写索引 详解
Netty Review - ByteBuf 读写索引 详解
60 1
|
17小时前
|
Java API
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf(二)
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf
31 0
|
17小时前
|
API 容器
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf(一)
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf
41 0
《跟闪电侠学Netty》阅读笔记 - 数据载体ByteBuf(一)
|
10月前
|
存储 Java API
Netty实战(五)ByteBuf—Netty的数据容器
网络数据的基本单位总是字节。Java NIO 提供了 ByteBuffer 作为它的字节容器,但是这个类使用起来过于复杂,而且也有些繁琐。**ByteBuffer 替代品是 ByteBuf**,一个强大的实现,既解决了 JDK API 的局限性,又为网络应用程序的开发者提供了更好的 API。
143 0
|
10月前
|
存储 Java Linux
Netty ByteBuf 的零拷贝(Zero Copy)详解
Netty ByteBuf 的零拷贝(Zero Copy)详解
130 0
|
10月前
Netty之ByteBuf解读(下)
Netty之ByteBuf解读(下)
|
10月前
|
Java
Netty之ByteBuf解读(中)
Netty之ByteBuf解读(中)
|
10月前
|
缓存 算法 Java