netty内存泄漏,困扰了好几天的问题找到原文了

本文详细介绍了Netty中引用计数的概念,包括如何创建、释放和增加引用计数,以及如何处理子缓冲和ByteBufHolder。特别强调了在不同组件间传递ByteBuf时的责任归属。此外,还探讨了如何处理引用计数对象在ChannelHandler中的使用,以及如何解决和排查内存泄漏问题。
摘要由CSDN通过智能技术生成

自从Netty 4开始,对象的生命周期由它们的引用计数(reference counts)管理,而不是由垃圾收集器(garbage collector)管理了。ByteBuf是最值得注意的,它使用了引用计数来改进分配内存和释放内存的性能。

 

基本的引用计数

 

每个对象的初始计数为1:

 

Java代码   收藏代码
  1. ByteBuf buf = ctx.alloc().directBuffer();  
  2. assert buf.refCnt() == 1;  

 

 

当你释放(release)引用计数对象时,它的引用计数减1.如果引用计数为0,这个引用计数对象会被释放(deallocate),并返回对象池。

 

Java代码   收藏代码
  1. assert buf.refCnt() == 1;  
  2. // release() returns true only if the reference count becomes 0.  
  3. boolean destroyed = buf.release();  
  4. assert destroyed;  
  5. assert buf.refCnt() == 0;  

 

 

 悬垂(dangling)引用

 

尝试访问引用计数为0的引用计数对象会抛出IllegalReferenceCountException异常:

 

Java代码   收藏代码
  1. assert buf.refCnt() == 0;  
  2. try {  
  3.   buf.writeLong(0xdeadbeef);  
  4.   throw new Error("should not reach here");  
  5. catch (IllegalReferenceCountExeception e) {  
  6.   // Expected  
  7. }  

 

 

增加引用计数

 

可通过retain()操作来增加引用计数,前提是此引用计数对象未被销毁:

(译者注:跟未使用ARC的objective-c好像)

 

Java代码   收藏代码
  1. ByteBuf buf = ctx.alloc().directBuffer();  
  2. assert buf.refCnt() == 1;  
  3.   
  4. buf.retain();  
  5. assert buf.refCnt() == 2;  
  6.   
  7. boolean destroyed = buf.release();  
  8. assert !destroyed;  
  9. assert buf.refCnt() == 1;  

 

谁来销毁(destroy)

 

通常的经验法则是谁最后访问(access)了引用计数对象,谁就负责销毁(destruction)它。具体来说是以下两点:

  • 如果组件(component)A把一个引用计数对象传给另一个组件B,那么组件A通常不需要销毁对象,而是把决定权交给组件B。
  • 如果一个组件不再访问一个引用计数对象了,那么这个组件负责销毁它。

 

下面是一个简单的例子:

 

Java代码   收藏代码
  1. public ByteBuf a(ByteBuf input) {  
  2.     input.writeByte(42);  
  3.     return input;  
  4. }  
  5.   
  6. public ByteBuf b(ByteBuf input) {  
  7.     try {  
  8.         output = input.alloc().directBuffer(input.readableBytes() + 1);  
  9.         output.writeBytes(input);  
  10.         output.writeByte(42);  
  11.         return output;  
  12.     } finally {  
  13.         input.release();  
  14.     }  
  15. }  
  16.   
  17. public void c(Byte
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值