相关类继承关系
其中,我们从AbstractByteBuf和他的子类开始分析,其他的多为衍生工具类。
上一节主要的源代码都是AbstractByteBuf中的,这里不再赘述其中的方法,其中的域如下所示:
其中有一个ResourceLeakDetector,用了装饰器模式实现,用于检测内存泄露(没有成对调用ByteBuf的retain和relaease方法,导致ByteBuf没有被正常释放),这里先跳过。
SwappedBytebuf用于翻转ByteBuf,也用了装饰器模式实现。
接下来看AbstractByteBuf的一个子类,AbstractReferenceCountedByteBuf 。这是用来做ByteBuf引用计数的类。这个引用计数用来跟踪内存的分配和销毁,以便于内存回收和检测内存泄露。
这里用到了原子更新字段类,AtomicIntegerFieldUpdater用于原子更新AbstractReferenceCountedByteBuf 的refCnt字段。refCnt就是引用计数。
静态初始化:
static {
//首先通过netty运用Unsafe创建AtomicIntegerFieldUpdater
AtomicIntegerFieldUpdater<AbstractReferenceCountedByteBuf> updater =
PlatformDependent.newAtomicIntegerFieldUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
//若创建不成功
if (updater == null) {
updater = AtomicIntegerFieldUpdater.newUpdater(AbstractReferenceCountedByteBuf.class, "refCnt");
}
refCntUpdater = updater;
}
这里有个netty的PlatformDependent类,用于检测运行环境,以及是否用java的Unsafe这个类。这个类是用于执行低级别、不安全操作的方法集合。尽管这个类和所有的方法都是公开的(public),但是这个类的使用仍然受限,你无法在自己的java程序中直接使用该类,因为只有授信的代码才能获得该类的实例。该类是用来执行较低级别的操作的,比如获取某个属性在内存中的位置等等,还有一些底层的IO操作。Java 8可能会将Unsafe剔除,netty通过设置“io.netty.noUnsafe”这个系统属性为true或false来开启或关闭使用Unsafe。
PlatformDependent.java:
/**
* Create a new optimized {@link AtomicIntegerFieldUpdater} or {@code null} if it
* could not be created. Because of this the caller need to check for {@code null} and if {@code null} is returned
* use {@link AtomicIntegerFieldUpdater#newUpdater(Class, String)} as fallback.
*/
public static <T> AtomicIntegerFieldUpdater<T> newAtomicIntegerFieldUpdater(
Class<?> tclass, String fieldName) {
if (hasUnsafe()) {
try {
return PlatformDependent0.newAtomicIntegerFieldUpdater(tclass, fieldName);
} catch (Throwable ignore) {
// ignore
}
}
return null;
}
PlatformDependent只是一个对外的暴露的类,真正的实现是
PlatformDependent:
PlatformDependent.java
static <T> AtomicIntegerFieldUpdater<T> newAtomicIntegerFieldUpdater(
Class<?> tclass, String fieldName) throws Exception { return new UnsafeAtomicIntegerFieldUpdater<T>(UNSAFE, tclass, fieldName); }
netty运用Unsafe自己实现的优化的UnsafeAtomicIntegerFieldUpdater:
final class UnsafeAtomicIntegerFieldUpdater<T> extends AtomicIntegerFieldUpdater<T> {
private final long offset;
private final Unsafe unsafe;
UnsafeAtomicIntegerFieldUpdater(Unsafe unsafe, Class<?> tClass, String fieldName) throws NoSuchFieldException {
Field field = tClass.getDeclaredField(fieldName);
if (!Modifier.isVolatile(field.getModifiers())) {
throw new IllegalArgumentException("Must be volatile");
}
this.unsafe = unsafe;
offset = unsafe.objectFieldOffset(field);
}
@Override
public boolean compareAndSet(T obj, int expect, int update) {
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
@Override
public boolean weakCompareAndSet(T obj, int expect, int update) {
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
@Override
public void set(T obj, int newValue) {
unsafe.putIntVolatile(obj, offset, newValue);
}
@Override
public void lazySet(T obj, int newValue) {
unsafe.putOrderedInt(obj, offset, newValue);
}
@Override
public int get(T obj) {
return unsafe.getIntVolatile(obj, offset);
}
}
这个原子更新类字段变量更新refCnt字段。
调用retian(),就是获取对于这个AbstractReferenceCountedByteBuf的引用。引用计数器加一。
public ByteBuf retain() {
for (;;) {
int refCnt = this.refCnt;
//如果引用计数器为0,这是不符合逻辑的,refCnt 初始为1,如果调用了正常次数的获取释放,引用计数器最小为1
if (refCnt == 0) {
throw new IllegalReferenceCountException(0, 1);
}
if (refCnt == Integer.MAX_VALUE) {
throw new IllegalReferenceCountException(Integer.MAX_VALUE, 1);
}
//CAS尝试更新refCnt为refCnt+1,如果更新成功则退出循环,否则继续更新
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) {
break;
}
}
return this;
}
public ByteBuf retain(int increment) {
if (increment <= 0) {
throw new IllegalArgumentException("increment: " + increment + " (expected: > 0)");
}
for (;;) {
int refCnt = this.refCnt;
if (refCnt == 0) {
throw new IllegalReferenceCountException(0, increment);
}
if (refCnt > Integer.MAX_VALUE - increment) {
throw new IllegalReferenceCountException(refCnt, increment);
}
if (refCntUpdater.compareAndSet(this, refCnt, refCnt + increment)) {
break;
}
}
return this;
}
对应的,release()就是释放