Netty小记——引用计数机制

2 篇文章 0 订阅
1 篇文章 0 订阅

引用计数机制在很多框架中都有使用,如果在游戏引擎框架coscos2dx中,这种机制可以很简单的进行对象的生命周期的管理,netty引用计数机制原文:http://netty.io/wiki/reference-counted-objects.html

Since Netty version 4, the life cycle of certain objects are managed by their reference counts, so that Netty can return them (or their shared resources) to an object pool (or an object allocator) as soon as it is not used anymore. Garbage collection and reference queues do not provide such efficient real-time guarantee of unreachability while reference-counting provides an alternative mechanism at the cost of slight inconvenience.

从netty的4.x版本开始,netty使用引用计数机制进行部分对象的管理,通过该机制netty可以很好的实现自己的共享资源池。如果应用需要一个资源,可以从netty自己的共享资源池中获取,新获取的资源对象的引用计数被初始化为1,可以通过资源对象的retain方法增加引用计数,当引用计数为0的时候该资源对象拥有的资源将会被回收。
这种方式相比于jvm的垃圾回收机制和引用队列机制来说更加实时高效,但是牺牲了一部分易用性。

资源初始化的时候引用计数为1

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

当需要释放资源的时候,调用release函数会将引用计数减一(release仅仅是减少引用计数,当引用计数为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;

如果资源对象的引用计数为0的时候,如果应用程序继续使用那么会抛出IllegalReferenceCountExeception异常

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

如果资源对象需要在多个逻辑中使用,可以通过retain来增加引用计数,从而可以避免引用计数为0时引起的异常引用的异常

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

buf.retain();
assert buf.refCnt() == 2;

boolean destroyed = buf.release();
assert !destroyed;
assert buf.refCnt() == 1;

谁负责释放资源,最后使用资源的负责释放资源,具体查看原文例子

如果netty自带的部分decode类返回的对象是引用计数的,那么只需要使用者在最后一个处理该自定义的handler中调用release方法即可(但是一定要调用,否则会造成内存泄漏

同样的在outbound handler中,如果应用层使用了带引用计数的对象,那么在outbound的pipeline的最后一个使用该对象的handler应该负责reease该对象,否则会出现内存泄漏

The disadvantage of reference counting is that it is easy to leak the reference-counted objects. Because JVM is not aware of the reference counting Netty implements, it will automatically GC them once they become unreachable even if their reference counts are not zero. An object once garbage collected cannot be resurrected, and thus cannot be returned to the pool it came from and thus will produce memory leak.
内存泄漏:在netty中的内存泄漏是指GC自动回收了refCnt>0的对象的内存,这种情况下使得该对象无法被重建,同时也无法被归还回到netty自己的缓冲区中,所以即使该内存被jvm GC可用了,但是应用层仍然标志了该内存被使用中,从而使得该块内存在应用的整个生命周期中无法被使用,造成了浪费。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值