diff --git a/README.md b/README.md index edccfb0..e64b583 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ - [HashedWheelTimer & schedule](docs/Netty/Netty技术细节源码分析/HashedWheelTimer&schedule.md) - [ByteBuf 的内存泄漏原因与检测原理](docs/Netty/Netty技术细节源码分析/ByteBuf的内存泄漏原因与检测原理.md) - [内存池之 PoolChunk 设计与实现](docs/Netty/Netty技术细节源码分析/内存池之PoolChunk设计与实现.md) +- [内存池之从内存池申请内存](docs/Netty/Netty技术细节源码分析/内存池之从内存池申请内存.md) ## Dubbo diff --git a/docs/Netty/Netty技术细节源码分析/内存池之从内存池申请内存.md b/docs/Netty/Netty技术细节源码分析/内存池之从内存池申请内存.md new file mode 100644 index 0000000..123baa9 --- /dev/null +++ b/docs/Netty/Netty技术细节源码分析/内存池之从内存池申请内存.md @@ -0,0 +1,29 @@ +该文所涉及的netty源码版本为4.1.16。 + +## Netty内存池申请内存流程 +在通股票PooledByteBufAllocator中向内存池中进行内存申请的时候,最先开始的步骤便是从PooledByteBufAllocator中一系列PoolArena数组中,选择其中一个PoolArena进行分配。 + +这时将会从PoolArena数组中选取当前使用量最小的PoolArena与当前线程通过ThreadLocal进行绑定,之后涉及到内存申请将会直接从这个PoolArena进行获取,这个做法在高并发情况下频繁往内存池中进行内存申请的时候可以减少资源竞争,提升效率。 + +在当前线程获取与其绑定的PoolArena之后,接下来就是从PoolArena中继续申请内存。 +为了适应各种大小的内存场景,PoolArena的组成也是为了其设计。 +- PoolSubpage数组 tinySubpagePools:默认情况下,当申请的内存小于512b的时候的时候将会从tinySubpagePools中直接选择subPage(内存池中的最小单位)返回 +- PoolSubpage数组 smallSubpagePools:默认情况下,当申请的内存大于512b但是小于一个page的大小(8kb)的时候,将会从smallSubpagePools返回一个subPage。subPage是由poolChunk中的page分配而来。 +- PoolChunkList qInit:存储内存利用率0-25%的poolChunk +- PoolChunkList q000:存储内存利用率1-50%的poolChunk +- PoolChunkList q025:存储内存利用率25-75%的poolChunk +- PoolChunkList q050:存储内存利用率50-100%的poolChunk +- PoolChunkList q075:存储内存利用率75-100%的poolChunk +- PoolChunkList q100:存储内存利用率100%的poolChunk、 +当申请的内存大于一个page(8kb)但又小于一个poolChunk(2048kb)总大小的时候,将会从各个PoolChunkList中尝试获取一个poolChunk从中返回。PoolChunkList是一个由poolChunk组成的链表。 +以上几个PoolChunkList,由符合各个内存利用率的poolChunk组成,这几个PoolChunkList之间又互相首尾连接组成队列,方便PoolChunk在各个队列中根据自己当前的利用率进行转移到对应的位置上。 +最后,当申请的内存大于一个poolChunk大小的时候将会直接申请一段非池化的内存返回,并不会占用内存池中的内存空间。 + +最后,到了从poolChunk中申请内存的场景,这一部分在[该文](https://github.com/doocs/source-code-hunter/blob/master/docs/Netty/Netty技术细节源码分析/内存池之PoolChunk设计与实现.md)中已经详细说明,这部分也是内存池中获取内存的最后一步。 + + + + + + +