netty 抽象字节buf引用计数器

本文详细介绍了Netty中的AbstractReferenceCountedByteBuf类,该类为ByteBuf实现提供了引用计数功能,包括引用计数器的原子更新、增加引用计数、释放引用等操作,并解释了如何在引用计数为0时释放资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

netty 字节buf定义:[url]http://donald-draper.iteye.com/blog/2393813[/url]
netty 资源泄漏探测器:[url]http://donald-draper.iteye.com/blog/2393940[/url]
netty 抽象字节buf解析:[url]http://donald-draper.iteye.com/blog/2394078[/url]
[size=medium][b]引言[/b][/size]
上一篇文章我们看了抽象字节buf,先来回顾一下:
字节buf内部有两个索引,一个读索引,一个写索引,两个索引标记,即读写索引对应的标记,buf的最大容量为maxCapacity;buf的构造,主要是初始化最大容量。

弃已读数据方法discardReadBytes,丢弃buf数据时,只修改读写索引和相应的标记,并不删除数据。

get*原始类型方法不会修改当前buf读写索引,getBytes(...,ByteBuf,...)方法不会修改当前buf读写索引,会修改目的buf的写索引。getBytes(...,byte[],...)方法不会修改当前buf读写索引。

set*原始类型方法不会修改当前buf读写索引,setBytes(...,ByteBuf,...)方法不会修改当前buf读写索引,会修改源buf的读索引。setBytes(...,byte[],...)方法不会修改当前buf读写索引。

read*原始类型方法会修改当前buf读索引,readBytes(...,ByteBuf,...)方法会修改当前buf读索引,同时会修改目的buf的写索引,readBytes(...,byte[],...)方法会修改当前buf读索引。read*操作实际委托个get*的相关操作,同时更新buf读索引。

跳过length长度的字节,只更新读索引,不删除实际buf数据。

retainedSlice和slice方法返回则的字节buf,实际为字节buf底层unwrap buf,可以理解为字节buf的快照或引用,数据更改相互影响,retainedSlice方法会增加字节buf的引用计数器。

write*原始类型方法会修改当前buf写索引,writeBytes(...,ByteBuf,...)方法会修改当前buf写索引,同时会修改目的buf的读索引,readBytes(...,byte[],...)方法会修改当前buf写索引。write*操作实际委托个set*的相关操作,同时更新buf写索引。

retainedDuplicate和duplicate方法返回则的字节buf,实际为字节buf底层unwrap buf,可以理解为字节buf的快照或引用,数据更改相互影响,retainedDuplicate方法会增加字节buf的引用计数器。


今天我们来看抽象引用字节buf AbstractReferenceCountedByteBuf:
package io.netty.buffer;

import io.netty.util.IllegalReferenceCountException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import static io.netty.util.internal.ObjectUtil.checkPositive;

/**
* Abstract base class for {@link ByteBuf} implementations that count references.
*/
public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf {
//引用计数器原子Updater
private static final AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> refCntUpdater =
AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");

private volatile int refCnt = 1;//引用计数器
protected AbstractReferenceCountedByteBuf(int maxCapacity) {
super(maxCapacity);
}
@Override
public int refCnt() {
return refCnt;
}
/**
* An unsafe operation intended for use by a subclass that sets the reference count of the buffer directly
*/
protected final void setRefCnt(int refCnt) {
this.refCnt = refCnt;
}
//增加引用计数器
@Override
public ByteBuf retain() {
return retain0(1);
}

@Override
public ByteBuf retain(int increment) {
return retain0(checkPositive(increment, "increment"));
}

private ByteBuf retain0(int increment) {
for (;;) {
int refCnt = this.refCnt;
final int nextCnt = refCnt + increment;

// Ensure we not resurrect (which means the refCnt was 0) and also that we encountered an overflow.
if (nextCnt <= increment) {
throw new IllegalReferenceCountException(refCnt, increment);
}
//原子更新引用计数器
if (refCntUpdater.compareAndSet(this, refCnt, nextCnt)) {
break;
}
}
return this;
}
//记录当前对象操作,以便提供内存泄漏的相关信息
@Override
public ByteBuf touch() {
return this;
}

@Override
public ByteBuf touch(Object hint) {
return this;
}
//释放对象引用
@Override
public boolean release() {
return release0(1);
}

@Override
public boolean release(int decrement) {
return release0(checkPositive(decrement, "decrement"));
}

private boolean release0(int decrement) {
for (;;) {
int refCnt = this.refCnt;
if (refCnt < decrement) {
throw new IllegalReferenceCountException(refCnt, -decrement);
}
//原子更新引用计数器
if (refCntUpdater.compareAndSet(this, refCnt, refCnt - decrement)) {
if (refCnt == decrement) {
//释放资源
deallocate();
return true;
}
return false;
}
}
}
/**
* Called once {@link #refCnt()} is equals 0.
*/
protected abstract void deallocate();
}

从上面可以看出,抽象字节引用计数器AbstractReferenceCountedByteBuf,内部有一个引用计数器,以及原子更新引用计数器的refCntUpdater(AbstractReferenceCountedByteBuf),更新引用计数器,实际通过refCntUpdater CAS操作,释放对象引用的时候,如果引用计数器为0,则释放对象相关资源。


[size=medium][b]总结:[/b][/size]
[color=blue]抽象字节引用计数器AbstractReferenceCountedByteBuf,内部有一个引用计数器,以及原子更新引用计数器的refCntUpdater(AbstractReferenceCountedByteBuf),更新引用计数器,实际通过refCntUpdater CAS操作,释放对象引用的时候,如果引用计数器为0,则释放对象相关资源。[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值