1、AbstractReferenceCountedByteBuf的类结构
- AbstractReferenceCountedByteBuf首先是一个抽象的abstract的类,而且继承AbstractByteBuf,从类里面可以看出有
release
、释放,retain
保留或记住方法,touch
触摸方法,refCnt引用数量
AbstractReferenceCountedByteBuf的类结构
2、AtomicIntegerFieldUpdater 类细节
- 1、compareAndSet发是原子性操作与硬件有关,如果当前值==期望值,则自动将此更新程序管理的给定对象的字段设置为给定的更新值,相对于其他对compareAndSet和set的调用,此方法保证是原子性的,但不一定相对于字段中的其他更改。
- 2、如果要更新的变量是包装类型,那么可以使用AtomicReferenceFieldUpdater
3、AtomicIntegerFieldUpdater 约束条件
- 1、更新器更新的必须是Int类型变量,不能是其他包装类型,
- 2、更新器更新必须是volatile类型变量(重排序,线程之间共享变量)
- 3、变量不能是static的,必须要是实例变量,因为unsafe.objectFieldOffset()方法,不支持静态变量(CAS操作本质上是通过对象实例的偏移量来进行赋值)
- 4、更新器只能修改它可见访问的变量,因为更新器是通过反射来得到这个变量,如果变量不可见就会报错
4、Unpooled未池化(重点)
- 分配10个未池化的内存:ByteBuf buffer = Unpooled.buffer(10);,用完就垃圾回收掉或是清空掉
- Unpooled提供诸多的
copiedBuffer
方法,用于拷贝内存的数据 - Unpooled
- Unpooled类的compositeBuffer方法代码
//静态复合字节缓存区
public static CompositeByteBuf compositeBuffer() {
return compositeBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS);
}
/**
* 无参数的compositeBuffer返回CompositeByteBuf 是调用一个有maxNumComponents的compositeBuffer方法
*/
public static CompositeByteBuf compositeBuffer(int maxNumComponents) {
return new CompositeByteBuf(ALLOC, false, maxNumComponents);
}
- 然而,compositeBuffer(int maxNumComponents) 方法是在CompositeByteBuf类里面,咋们分析一下这个方法的代码含义
public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents) {
//调用AbstractReferenceCountedByteBuf类的构造方法AbstractReferenceCountedByteBuf,给一个Integer.MAX_VALUE;最大值
super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
if (alloc == null) {
throw new NullPointerException("alloc");
}
this.alloc = alloc;//分配
this.direct = direct;//直接缓存
//最大数量的组件
this.maxNumComponents = maxNumComponents;
components = newList(maxNumComponents); //给一个默认最大的组件
}
private static List<Component> newList(int maxNumComponents) {
return new ArrayList<Component>(Math.min(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, maxNumComponents));
}
5、引用对象
- 对于引用对象进行加1还是减1取决ByteBuf的非池化处理,引用回收处理是根据谁最后调用的一方进行处理被回收
- ByteBuf不是唯一的引用计数对象
6、ReferenceCountUtil详解
- Netty为此提供了一个实用方法ReferenceCountUtil.release() 但是以这种方式管理资源可能很繁琐
- release 、safeRelease、touch、retain
- ReferenceCountUtil代码
public static <T> T retain(T msg) {
return msg instanceof ReferenceCounted?((ReferenceCounted)msg).retain():msg;
}
public static <T> T retain(T msg, int increment) {
return msg instanceof ReferenceCounted?((ReferenceCounted)msg).retain(increment):msg;
}
7、Netty提供内存泄漏检测的方式
- 通过log打印,无非release或retain方法的合理调用
java -Dio.netty.leakDetectionLevel=advanced
Dio.netty.leakDetectionLevel=paranoid
public static final ResourceLeakDetector.Level ADVANCED
public static final ResourceLeakDetector.Level PARANOID
-
IDEA或Eclipse的VM options设置打印
VM options设置