如果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的池不知道.然后池会增长,相信你使用越来越多的缓冲区,这些缓冲区永远不会返回到池中.这可能会产生内存泄漏,因为即使缓冲区本身被垃圾回收,用于存储池的内部数据结构将不会.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Netty实现httpserver简单示例 3个Java类实现最基本的接收请求,响应一个文本的简单http服务器。 https://www.cnblogs.com/demingblog/p/99707
Java NIO系列1 概观 Java NIO。中间的N你既可以理解为(new),也就是新的IO,相对于java1.5之前的IO它确实是新的;也可以理解为(no blocking),也就是非阻塞的IO
关键字:使用Netty实现HTTP服务器,使用Netty实现httpserver,Netty Http server Netty是一个异步事件驱动的网络应用程序框架用于快速开发可维护的高性能协议服务器
netty心跳机制示例,使用Netty实现心跳机制,使用netty4,IdleStateHandler 实现。Netty心跳机制,netty心跳检测,netty,心跳 本文假设你已经了解了Netty的
关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议。redis客户端,netty redis协议
前提 最近一直在看Netty相关的内容,也在编写一个轻量级的RPC框架来练手,途中发现了Netty的源码有很多亮点,某些实现甚至可以用苛刻来形容。另外,Netty提供的工具类也是相当优秀,可以开箱即用
前言 最近在调研Netty的使用,在编写编码解码模块的时候遇到了一个中文字符串编码和解码异常的情况,后来发现是笔者犯了个低级错误。这里做一个小小的回顾。 错误重现 在设计Netty的自定义协议的时候,
我正在研究Netty应用程序.我想在不同的端口上运行多个服务器,如果没有(阻塞)closeFuture().sync(),它就无法工作. 我使用以下代码在ServerManager类中启动服务器: gpcmServer = new GpcmServer(port); gpspServer = new GpspServer(port); 在这些类中,我按如下方式启动服务器: public Gpsp
之前写了一篇文章:Java网络IO编程总结(BIO、NIO、AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即JavaNIO框架。
游戏一般是长连接,自定义协议,不用http协议,BIO,NIO,AIO这些我就不说了,自己查资料
netty处理客户端传过来的get、post、websocket数据例子
利用Netty中提供的HttpChunk简单实现文件传输
我正在为我的项目制作Netty原型.我试图在Netty上实现一个简单的面向文本/字符串的协议.在我的管道中,我使用以下内容: public class TextProtocolPipelineFactory implements ChannelPipelineFactory { @Override public ChannelPipeline getPipeline() throws Except
我是Netty的新手,我正在使用它来创建一个简单的http代理服务器,它接收来自客户端的请求,将请求转发给另一个服务器,然后将响应复制回原始请求的响应.一个额外的要求是我能够支持超时,因此如果代理服务器花费太长时间来响应,代理将自行响应并关闭与代理服务器的连接.我已经使用Jetty实现了这样的应用程序,但是使用Jetty我需要使用太多的线程来阻止入站请求被阻
对于我使用netty nio lib在 Java中开发的下载客户端,我还实现了带宽限制功能.从技术上讲,我是通过GlobalTrafficShapingHandler对象完成的.基于这个类’JavaDoc我初始化nio客户端管道如下: ... trafficHandler = new GlobalTrafficShapingHandler( new HashedWheelTimer
我正在使用Netty 4.1 Beta3构建一个消息传递应用程序来设计我的服务器,并且服务器理解MQTT协议. 这是我的MqttServer.java类,它设置Netty服务器并将其绑定到特定端口. EventLoopGroup bossPool=new NioEventLoopGroup(); EventLoopGroup workerPool=new NioEventLoopG
我在我的Apache服务器上设置了MOD_SPDY,现在想要改进我的客户端代码,使用Netty的SPDY实现通过SPDY通道将我的请求发送到服务器. 这是我第一次使用Netty的经历,所以我想我得到了我需要以某种方式配置我的频道,然后通过它发送请求.问题是,它似乎不清楚如何配置通道,甚至在此之后,如何跟踪可能同时执行的通道内的多个HTTP请求. 我用Google搜索并找到了SPDY包: http:
您好我有一个Netty Server,其处理程序应该接受字符串.它似乎只接收最多1024个字节的内容.如何增加缓冲区大小.我已经尝试过了 bootstrap.setOption("child.sendBufferSize", 1048576); bootstrap.setOption("child.receiveBufferSize", 1048576); 没有成功. 处理程序如下 public
我需要使客户端能够进行很多连接.我使用Netty 4.0.不幸的是,所有现有的示例都不显示如何创建大量的连接. public class TelnetClient { private Bootstrap b; public TelnetClient() { b = new Bootstrap(); } public void connect(Stri
根据Netty in Action v10的说法,引用计数用于处理ByteBuf的汇总.但是JVM不知道netty引用计数,所以JVM仍然可以使用ByteBuf.如果是这样,为什么还需要关心引用计数和手动调用release()方法? 我从书中引用了一些, Netty in Action v10>添加一些上下文. One of the tradeoffs of reference-counting