Netty源码分析:PoolArena

本文深入解析Netty的PoolArena,它是内存池的实现类,由多个PoolChunk组成,每个PoolChunk包含PoolSubpage。PoolArena通过6个PoolChunkList管理不同内存使用情况的PoolChunk。PoolArena使用tinySubpagePools和smallSubpagePools来缓存分配tiny和small内存的Page。内存分配过程包括从PoolThreadCache、tinySubpagePools、smallSubpagePools或通过allocateNormal方法进行。文章详细介绍了PoolArena的属性、构造函数以及内存分配策略。
摘要由CSDN通过智能技术生成

Netty源码分析:PoolArena

Arena本身是指一块区域,在内存管理中,Memory Arena是指内存中的一大块连续的区域,PoolArena就是Netty的内存池实现类。

Netty的PoolArena是由多个Chunk组成的大块内存区域,而每个Chunk则由一个或者多个Page组成(在博文Netty源码分析:PoolChunk已经明确了这点),因此,对内存的组织和管理也就主要集中在如何管理和组织Chunk和Page了。

先说结论:PoolArena通过6个PoolChunkList来管理PoolChunk,而每个PoolChunk由N个PoolSubpage构成,即将PoolChunk的里面底层实现 T memory分成N段,每段就是一个PoolSubpage。当用户申请一个Buf时,使用Arena所拥有的chunk所管辖的page分配内存,内存分配的落地点为 T memory上。

看一个例子

假设每个Page的大小为8192。在下面的代码中就是申请两块buf。所得到的结果就是:byteBuf将利用PoolChunk的第0个PoolSubpage进行分配,分配的buf的内存为:从memory[0]开始且长度为15最大长度为16;byteBuf1将利用PoolChunk的第1个PoolSubpage进行分配,分配的落地点从memory[8192]开始且长度为17最大长度为32的内存.

截图如下:

    public class TestByteBuf {

        public static void main(String[] args) {
            //1 分配一个ByteBuf,然后写入数据到此Buf

            PooledByteBufAllocator allocator = new PooledByteBufAllocator(false);
            ByteBuf byteBuf = allocator.heapBuffer(15);

            ByteBuf byteBuf1 = allocator.heapBuffer(17);

            String content = "wojiushimogui";
            byteBuf.writeBytes(content.getBytes());
            System.out.println("1、readerIndex:"+byteBuf.readerIndex());
            System.out.println("1、writerIndex:"+byteBuf.writerIndex());
        }
    }

本文将从源码的角度主要介绍下PoolArena。

1、属性

    abstract class PoolArena<T> {

        static final int numTinySubpagePools = 512 >>> 4;

        final PooledByteBufAllocator parent;//表示该PoolArena的allocator

        private final int maxOrder;//表示chunk中由Page节点构成的二叉树的最大高度。默认11
        final int pageSize;//page的大小,默认8K
        final int pageShifts;//pageShifts=log(pageSize),默认13
        final int chunkSize;//chunk的大小
        final int subpageOverflowMask;//该变量用于判断申请的内存大小与page之间的关系,是大于,还是小于

        final int numSmallSubpagePools;//用来分配small内存的数组长度
        /*
        tinySubpagePools来缓存(或说是存储)用来分配tiny(小于512)内存的Page;
        smallSubpagePools来缓存用来分配small(大于等于512且小于pageSize)内存的Page
        */
        private final PoolSubpage<T>[] tinySubpagePools;
        private final PoolSubpage<T>[] smallSubpagePools;
        //用来存储用来分配给Normal(超过一页)大小内存的PoolChunk。
        private final PoolChunkList<T> q050;
        private final PoolChunkList<T> q025;
        private final PoolChunkList<T> q000;
        private final PoolChunkList<T> qInit;
        private final PoolChunkList<T> q075;
        private final PoolChunkList<T> q100;

PoolArena属性的各个含义已在代码中进行了解释哈。下面来看构造函数。

2、构造函数

构造函数的代码如下:

        protected PoolArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) {
        //从PooledByteBufAllocator中传送过来的相关字段值。
            this.parent = parent;
            this.pageSize = pageSize;
            this.maxOrder = maxOrder;
            this.pageShifts = pageShifts;
            this.chunkSize = chunkSize;
            subpageOverflowMask = ~(pageSize - 1);//该变量用于判断申请的内存大小与page之间的关系,是大于,还是小于
            tinySubpagePools = newSubpagePoolArray(numTinySubpagePools);
            for (int i = 0; i < tinySubpagePools.length; i ++) {
                tinySubpagePools[i] = newSubpagePoolHead(pageSize);
            }

            numSmallSubpagePools = pageShifts - 9;
            smallSubpagePools = newSubpagePoolArray(numSmallSubpagePools);
            for (int i = 0; i < smallSubpagePools.length; i ++) {
                smallSubpagePools[i] = newSubpagePoolHead(pageSize);
            }

            q100 = new PoolChunkList<T>(this, null, 100, Integer.MAX_VALUE);
            q075 = new PoolChunkList<T>(this, q100, 75, 100);
            q050 = new PoolChunkList<T>(this, q075, 50, 100);
            q025 = new PoolChu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值