如果JVM GC仍然存在,为什么需要手动处理Netty ByteBuf的引用计数?

根据Netty in Action v10的说法,引用计数用于处理ByteBuf的汇总.但是JVM不知道netty引用计数,所以JVM仍然可以使用ByteBuf.如果是这样,为什么还需要关心引用计数和手动调用release()方法

我从书中引用了一些,Netty in Action v10>添加一些上下文.

One of the tradeoffs of reference-counting is that the user have to be
carefully when consume messages. While the JVM will still be able to
GC such a message (as it is not aware of the reference-counting) this
message will not be put back in the pool from which it may be obtained
before. Thus chances are good that you will run out of resources at
one point if you do not carefully release these messages.

和一些相关的线程:
Buffer ownership in Netty 4: How is buffer life-cycle managed?

https://blog.twitter.com/2013/netty-4-at-twitter-reduced-gc-overhead

添加1

(以下是我的一些理解.)

ByteBuf可以从2个角度分类

1. Pooled or Unpooled
2. Heap-based or Direct

所以可以有4种组合:

(a) Pooled Heap-based
(b) Pooled Direct
(c) Unpooled Heap-based
(d) Unpooled Direct

只有(a)和(c)受到JVM GC机制的影响,因为它们是基于堆的.

在上述的< Netty in Action v10>,我认为该消息是指一个Java对象,它是(a)类别.

一个最终的规则是,如果一个Java对象是GCed,它完全消失了.以下是我认为Netty所做的:

>对于(a),Netty分配器必须欺骗JVM GC相信对象不应该被GCed.然后使用引用计数将对象移出/返回到池中.这是生命周期的另一种形式.
>对于(b),JVM GC不涉及,因为它不是基于JVM堆的.而Netty分配器需要使用引用计数将对象移出/返回到池中.
>对于(c),JVM GC全权负责控制物体的使用寿命. Netty分配器只提供用于分配对象的API.
>对于(d),不涉及JVM GC.而且不需要汇集.所以Netty分配器只需要提供分配/释放对象的API.

解决方法

直接缓冲区被垃圾收集器间接释放.我会让你阅读这个问题的答案,以了解如何发生: Are Java DirectByteBuffer wrappers garbage collected?

当您执行I / O操作时,堆内存需要被内核处理之前复制到直接内存中.当您使用直接缓冲区时,保存该复制操作,这是使用直接缓冲区的主要优点.缺点是直接内存分配比从java堆分配更为昂贵,因此Netty引入了池化概念.

Java中的对象是一个polemic topic,但是Netty的选择似乎有所回报,而您引用的Twitter article显示了一些证据.对于分配缓冲区的具体情况,当缓冲区的大小很大时,您可以看到它在直接和堆缓冲区情况下真正带来好处.

现在要进行池化,GC在汇总时不会回收缓冲区,因为在使用缓冲区时,您的应用程序有一个或多个引用;或Netty的池有一个引用,当它刚刚被分配,还没有被给予你的应用程序,或者你的应用程序使用它,并把它还给池.

当您的应用程序在使用缓冲区并没有进一步引用它之后,会发生泄漏,不会调用release(),实际上意味着将其放回池中,如果您没有进一步的参考.在这种情况下,缓冲区最终将被垃圾回收,但Netty的池不知道.然后池会增长,相信你使用越来越多的缓冲区,这些缓冲区永远不会返回到池中.这可能会产生内存泄漏,因为即使缓冲区本身被垃圾回收,用于存储池的内部数据结构将不会.

相关文章

Netty实现httpserver简单示例 3个Java类实现最基本的接收请求,响应一个文本的简单http服务器。 https:...
Java NIO系列1 概观 Java NIO。中间的N你既可以理解为(new),也就是新的IO,相对于java1.5之前的IO它确...
关键字:使用Netty实现HTTP服务器,使用Netty实现httpserver,Netty Http server Netty是一个异步事件驱...
netty心跳机制示例,使用Netty实现心跳机制,使用netty4,IdleStateHandler 实现。Netty心跳机制,nett...
关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议...
前提 最近一直在看Netty相关的内容,也在编写一个轻量级的RPC框架来练手,途中发现了Netty的源码有很多...