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

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

  1. ios – Netty Channel关闭检测

    我正在使用netty和ios构建服务器客户端应用程序,当用户在他/她的ios设备上关闭WiFi时,我遇到问题,netty服务器不了解它.服务器需要知道为该用户进行清理并将其设置为离线状态,但是当用户再次尝试连接时,服务器只是告诉他他/她已经在线.解决方法如果我正确地理解了您的问题:您想要监听服务器端的客户端通道关闭事件,并进行一些会话清理,在Netty有两种方式来收听频道封闭事件:1)如果您的服务

  2. android – 基于JVM的语言,没有语言运行时

    ProGuard可以删除特定程序中未使用的部分运行时.如果速度和时间非常关键,另一种方法是使用NDK.

  3. android – 如何在gradle中调整dex内存的jvm args?

    我有一个Android项目,它在dex步骤中当前没有堆空间:我想在gradle中提高jvmmin/max设置,就像我们以前使用Maven插件一样:但是在gradle中的android插件的文档中我只看到这些选项:有办法吗?

  4. Android MINA vs netty for Android

    在here,MINA和netty之间有一个非常翔实的比较当平台是Android时,我想知道您的偏好!>我有一个主机应该接受连接以及建立与Android设备的连接.>该主机为其操作实现了Boost.ASIO.我需要为android方面选择一个简单的框架.>基于几个小时的谷歌搜索,我,相当新的java,缩小到MINA和netty.两者似乎都很好,虽然netty似乎更容易.>当我读到一些关于在android中使用netty的bug报告时,我感到很困惑.>连接到主机的Android模拟器数量可以增长到很多.所以问

  5. android – Timer()作为守护进程与非守护进程

    什么时候应该在Android应用程序中作为守护进程启动计时器?

  6. JVM的常用命令汇总

    监测java应用,最方便的就是直接使用jdk提供的现成工具,在jdk的安装的bin目录下,已经提供了多种命令行监测工具。本文为大家总结了几个JVM的常用命令,需要的可以参考一下

  7. Java JVM虚拟机调优详解

    JVM是JavaVirtualMachine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的,本文主要介绍了jvm调优,感兴趣的小伙伴们可以参考一下<BR>

  8. Java JVM中线程状态详解

    这篇文章主要介绍了Java JVM中线程状态详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的朋友可以参考一下

  9. JVM jstack实战之死锁问题详解

    如果在生产环境发生了死锁,我们将看到的是部署的程序没有任何反应了,这个时候我们可以借助 jstack进行分析,下面我们实战操作查找死锁的原因

  10. java自旋锁和JVM对锁的优化详解

    这篇文章主要为大家介绍了java自旋锁和JVM对锁的优化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

随机推荐

  1. java – Netty增加ChannelBuffer大小

    您好我有一个NettyServer,其处理程序应该接受字符串.它似乎只接收最多1024个字节的内容.如何增加缓冲区大小.我已经尝试过了没有成功.处理程序如下}解决方法你在使用UDP吗?

  2. java – 使用SPDY和Netty

    此外,当服务器不支持SPDY并且通道回退到标准SSL连接时,该功能如何?

  3. java – Linux机器上Netty 4.1的性能调优

    我正在使用Netty4.1Beta3构建一个消息传递应用程序来设计我的服务器,并且服务器理解MQTT协议.这是我的MqttServer.java类,它设置Netty服务器并将其绑定到特定端口.现在,我在Mac上对我的应用程序进行了负载测试,具有以下配置网络性能非常出色.在执行我的代码时我查看了jstack,发现nettyNIO产生了大约19个线程,并且它们似乎都没有等待等待通道或其他东西.然后我在

  4. 如何使用Java netty正确限制带宽使用?

    在此先感谢您的帮助!

  5. java – Netty 4多客户端

    我需要使客户端能够进行很多连接.我使用Netty4.0.不幸的是,所有现有的示例都不显示如何创建大量的连接.这是正确的决定吗?

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

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

返回
顶部