看了前面的PoolArena分析,我们知道PoolArena在分配内存时,使用了synchronized来保证线程安全,这样就带来了一定的效率问题。如何能再此基础上再优化呢,答案很简单,使用ThreadLocal类似的解决方案避免加锁! 为什么可以使用ThreadLocal,如果了解过netty线程模型(有兴趣后续可以一起学习),应该知道netty的woker线程池,它负责了数据的接收、发送(编解码这里先不说),并且保证同一个连接在同一个线程中完成这两个步骤,因此很容易利用ThreadLocal进行内存的分配和回收优化。
下面我们来看看内存池内存分配流程:
1、ByteBufAllocator 准备申请一块内存;
2、尝试从PoolThreadCache中获取可用内存,如果成功则完成此次分配,否则继续往下走,注意后面的内存分配都会加锁;
3、如果是小块(可配置该值)内存分配,则尝试从PoolArena中缓存的PoolSubpage中获取内存,如果成功则完成此次分配;
4、如果是普通大小的内存分配,则从PoolChunkList中查找可用PoolChunk并进行内存分配,如果没有可用的PoolChunk则创建一个并加入到PoolChunkList中,完成此次内存分配;