PooledHeapByteBuf,带有池的堆内buffer,顾名思义,肯定比一般通过new出来的buffer性能好。把对象放入对象池缓存起来,一般都是因为创建该对象开销比较大,常见的有线程池(ThreadPool)、连接池(ConnectionPool)等。
PooledHeapByteBuf继承关系如下:
PooledHeapByteBuf –》 PooledByteBuf –》 AbstractReferenceCountedByteBuf –》 AbstractByteBuf –》 ByteBuf。
继承关系比较简单清晰。
先介绍几个相关的类:
PooledByteBufAllocator:buffer分配器,用来分配buffer(包括堆内和堆外)。
PoolArena:一块逻辑上的内存池,用来管理和组织buffer的,内部数据结构较复杂。
FastThreadLocal:较快的ThreadLocal(相对于jdk自带的),实现:线程T扩展于FastThreadLocalAccess,InternalThreadLocalMap是它的成员变量,set()时放入InternalThreadLocalMap的成员变量数组,下标是index,get()时从InternalThreadLocalMap的成员变量数组中下标是index处取。
Recycler:回收器,基于FastThreadLocal,缓存的本地对象是个stack,stack里装的是Handler,handler里装的buffer。新建buffer时,从Recycler中的FastThreadLocal取,FastThreadLocal取出当前线程的本地变量stack,stack.pop()弹出handler,handler调用newObject()生成。
练习代码debug下:
1 2 3 4 5 | < dependency > < groupId >io.netty</ groupId > < artifactId >netty-all</ artifactId > < version >5.0.0.Alpha2</ version > </ dependency > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.zoo; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.util.concurrent.FastThreadLocalThread; /** * * @author yankai913@gmail.com * @date 2015-3-31 */ public class PooledHeapByteBufTest { static PooledByteBufAllocator alloc = new PooledByteBufAllocator(); static void singleThread() { new FastThreadLocalThread( new Runnable() { @Override public void run() { for ( int i = 0 ; i < 3 ; i++) { String name = Thread.currentThread().getName(); long start = System.currentTimeMillis(); ByteBuf buf = alloc.buffer( 102400 ); long end = System.currentTimeMillis(); System.out.println(name + "\t" + buf + ", time:" + (end - start)); } } }).start(); } public static void main(String[] args) throws Exception { singleThread(); } } |
打印结果:
Thread-1 SimpleLeakAwareByteBuf(PooledHeapByteBuf(ridx: 0, widx: 0, cap: 102400)), time:62
Thread-1 PooledHeapByteBuf(ridx: 0, widx: 0, cap: 102400), time:0
Thread-1 PooledHeapByteBuf(ridx: 0, widx: 0, cap: 102400), time:0