Netty-对象引用计数

智数探秘
• 阅读 903

引言

Netty 4.0 之后,netty中某些对象的生命周期由它们的引用计数管理,如ByteBuf是利用引用计数来提高分配和释放性能的最著名类型.

引用计数

—1—引用计数对象的初始引用计数为 1。
—2—当释放引用计数对象时,它的引用计数减 1。

一般法则是,最后访问引用计数对象的一方也负责销毁该引用计数对象。具体来说:
如果 [发送] 组件应该将引用计数对象传递给另一个 [接收] 组件,发送组件通常不需要销毁它,而是将决定推迟到接收组件。
如果一个组件使用了一个引用计数的对象并且知道没有其他人会再访问它(即,不传递对另一个组件的引用),则该组件应该销毁它。

—3—如果引用计数达到 0,则引用计数对象被释放或返回到它来自的对象池,尝试访问引用计数为 0 的引用计数对象将触发IllegalReferenceCountException。
—4—当对象还没有被销毁之前,引用计数也可以通过retain()操作增加。

Derived buffers

—1—ByteBuf.duplicate()、ByteBuf.slice()及ByteBuf.order(ByteOrder)创建一个共享父缓冲区内存区域的派生缓冲区。派生缓冲区没有自己的引用计数,但共享父缓冲区的引用计数。
—2—相反,ByteBuf.copy()和ByteBuf.readBytes(int)不是派生缓冲区。返回ByteBuf的已分配,需要释放。需要注意的是,父缓冲区及其派生缓冲区共享相同的引用计数,并且创建派生缓冲区时引用计数不会增加。因此,如果您要将派生缓冲区传递给应用程序的其他组件,则必须先调用retain()它。

ByteBufHolder interface

可使用ByteBufHolder 持有 ByteBuf,例如DatagramPacket、HttpContent和WebSocketframe .这些类都继承自ByteBufHolder。和Derived buffers一样,ByteBufHolder持有者共享其包含的缓冲区的引用计数。

ChannelHandler 的引用计数

Inbound messages(入站消息)

—1—当事件循环将数据读入ByteBuf并触发channelRead()事件时,ChannelHandler相应管道中的 负责释放缓冲区。因此,使用接收到的数据的处理程序应该release()在其channelRead()处理程序方法中调用数据。
—2—如果处理程序将缓冲区(或任何引用计数对象)传递给下一个处理程序,则无需释放它。
—3—可以直接使用ReferenceCountUtil.release(),或考虑扩展SimpleChannelHandlerwhich 对所有消息调用ReferenceCountUtil.release(msg)。

Outbound messages(出站消息)

与入站消息不同,出站消息是由自己的应用程序创建的,Netty 负责在将它们写入网络后释放这些消息。

特别注意encoders之后正确释放。

Mpsc Queue

Mpsc 的全称是 Multi Producer Single Consumer,多生产者单消费者。Mpsc Queue 可以保证多个生产者同时访问队列是线程安全的,而且同一时刻只允许一个消费者从队列中读取数据。Netty Reactor 线程中任务队列 taskQueue 必须满足多个生产者可以同时提交任务,所以 JCTools 提供的 Mpsc Queue 非常适合 Netty Reactor 线程模型。

MpscArrayQueue

—1—通过大量填充 long 类型变量解决伪共享问题。
—2—环形数组的容量设置为 2 的次幂,可以通过位运算快速定位到数组对应下标。
—3—入队 offer() 操作中 producerLimit 的巧妙设计,大幅度减少了主动获取消费者索引 consumerIndex 的次数,性能提升显著。
—4—入队和出队操作中都大量使用了 UNSAFE 系列方法,针对生产者和消费者的场景不同,使用的 UNSAFE 方法也是不一样的。Jctools 在底层操作的运用上也是有的放矢,把性能发挥到极致。

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
java 面试知识点笔记(四)垃圾回收 上篇
问:对象判定为垃圾的标准?没有被其他对象引用问:对象判定为垃圾的算法?引用计数算法通过判断对象的引用数量来判断对象是否可以被回收每个对象实例都有一个引用计数器,被引用则1,完成引用1任何引用计数为0的对象实例可以当垃圾收集的    优点:执行效率高,程序受影响较小    缺点:无法检测出
九路 九路
5年前
4 Java 如何判定是否存活或者死亡
在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去.判断对象是否已经死亡有以下几种算法:引用计数法算法定义:给对象中添加一个引用计数器,当有一个地方引用时,计数器加1,引用失效时,就减1,当对象的引用计数器为0时,对象就是不可再被使用的.特点:JAVA虚拟机中很少使用这
xiguaapp xiguaapp
4年前
垃圾回收机制
GC标记算法对象被判定为垃圾的标准:没有被其他对象引用引用计数算法:判断对象的引用数量:通过判断对象的引用数量来决定对象是否可以被回收每个对象实例都有一个引用计数器,被引用则1,完成引用则1任何引用计数为0的对象实例可以被当做垃圾收集优点:执行效率高,程序执行受影响较小。
Stella981 Stella981
4年前
Python C 扩展的引用计数问题探讨
PythonGC机制对于Python这种高级语言来说,开发者不需要自己管理和维护内存。Python采用了引用计数机制为主,标记清除和分代收集两种机制为辅的垃圾回收机制。首先,需要搞清楚变量和对象的关系:变量:通过变量指针引用对象。变量指针指向具体对象的内存空间,取对象的值。对象,类型已知,每个对象都包
Stella981 Stella981
4年前
JVM学习第二天
引用计数算法对象中添加一个引用计数,一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减一两对象互相引用,就会造成死循环,无法回收可达性分析算法通过GCRoots作为起点,向下搜索,到达不了的对象,即证明对象不可用GCRoots包括:虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用
Stella981 Stella981
4年前
JVM笔记整理
不对之处还望指正。垃圾回收1\.如何判断对象是垃圾对象?引用计数法在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值1,当引用失效时,则值1.此方式不能解决循环引用的问题。验证添加gc日志,\_005GC.javaverbose:gc
Stella981 Stella981
4年前
JVM垃圾回收算法
一、如何判断对象时候需要回收1.引用计数法        给对象添加一个引用计数器,每当有一个地方引用它,计数器加1;引用失效时,计数器减1。计数器为0的对象就表示不可用。      优点:效率高,实现简单。      缺点:对象间如果存在循环引用的情况,就会导致计数器不可能为0,计数器无法通知GC进行回收。2.可达性分析算法
Wesley13 Wesley13
4年前
PHP垃圾回收机制
php5.3之前使用的垃圾回收机制是单纯的“引用计数”,也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器1;当变量引用撤掉后,计数器1;当计数器0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。“引用计数”存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时候,这一组内存对象已经
Stella981 Stella981
4年前
JVM调优总结(三)
可以从不同的的角度去划分垃圾回收算法:按照基本回收策略分引用计数(ReferenceCounting):比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。标记清除(MarkSweep):
Stella981 Stella981
4年前
JVM垃圾回收机制
引用计数法:当给对象添加一个引用计数器,每当有一个地方引用这个对象时计数器值就1;引用失效时,计数器值就1;任何时刻计数器为0的对象就是不可能在被使用。优点:引用计数收集器可以很快地执行,交织在程序运行中。缺点:无法检测出循环引用。例如:MyObjectobject1newMyObject();MyObjectobject2
Stella981 Stella981
4年前
JVM03
前言今天来学习下与JVM垃圾收集机制相关的一些基本概念。如何判断对象是否存活垃圾收集器首要的任务的任务就是判断哪些对象是存活的,哪些对象已经死去了(这里死去的意思是对象不再被任何途径使用)。引用计数算法引用计数算法是在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器
智数探秘
智数探秘
Lv1
今日听君歌一曲,暂凭杯酒长精神。
文章
5
粉丝
0
获赞
0