Tiny memory allocation
Tiny memory allocation process:
 
 
  
  - If the tiny type is requested, the allocation is first attempted from the tiny cache and returned if the cache allocation succeeds 
- Otherwise, try assigning from Tinysubpagepools
- Use Allocatenormal to allocate if there are no assignments above 
Allocating from the cache
In this case, the cache is enabled as an example, the cache class used is Poolthreadcache, the cache is implemented by the queue, and the memory size stored in a queue is the same
Io.netty.buffer.poolarena#allocate (Io.netty.buffer.PoolThreadCache, Io.netty.buffer.pooledbytebuf<t>, int)//The cache here is Poolthreadcacheif (Cache.allocatetiny (this, buf, reqcapacity, normcapacity)) {//were able to allocate Out of the cache so move on return; Boolean Allocatetiny (poolarena<?> area, pooledbytebuf<?> buf, int reqcapacity, int normcapacity) {//cache maintained A queue in which the block size of memory stored in the queue is the same//after the cache is found, a memory block is removed from the queue to initialize the buffer return allocate (Cachefortiny (area, normcapacity), buf, Reqcap acity);} Find cached memory in cache array private memoryregioncache<?> cachefortiny (poolarena<?> area, int normcapacity) {//Calculate request Memory bit    The position in the cache array, that is, the array subscript int idx = POOLARENA.TINYIDX (normcapacity);    if (Area.isdirect ()) {//Use the direct memory cache with the return cache (tinysubpagedirectcaches, IDX); }//cache with heap memory return cache (tinysubpageheapcaches, idx);} static int tinyidx (int normcapacity) {///Because the tiny cache array size is 32, the corresponding memory size is 16, 32...,512, so the subscript of the array should be the size of the request memory divided by//Normcapaci Ty = NorMCAPACITY/16 return normcapacity >>> 4;} 
The process of allocating memory from the cache
 
 
  
  - Looking for cache tinysubpagedirectcaches
- Initialize the BUF using chunk in the cache
About the data structure of the tiny cache
// tiny缓存// 是一个SubPageMemoryRegionCache数组,默认缓存数组长度:32,依次存储的内存大小是16、32、48...,512io.netty.buffer.PoolThreadCache#tinySubPageDirectCaches// 初始化tiny缓存数组,数组大小是32// static final int numTinySubpagePools = 512 >>> 4;tinySubPageDirectCaches = createSubPageCaches(                    tinyCacheSize, PoolArena.numTinySubpagePools, SizeClass.Tiny);// 初始化tiny和small缓存数组private static <T> MemoryRegionCache<T>[] createSubPageCaches(    int cacheSize, int numCaches, SizeClass sizeClass) {    if (cacheSize > 0) {        @SuppressWarnings("unchecked")        MemoryRegionCache<T>[] cache = new MemoryRegionCache[numCaches];        for (int i = 0; i < cache.length; i++) {            // TODO: maybe use cacheSize / cache.length            cache[i] = new SubPageMemoryRegionCache<T>(cacheSize, sizeClass);        }        return cache;    } else {        return null;    }}
Cache usage Queue implementation, maximum number of elements in a queue
Default_tiny_cache_size = Systempropertyutil.getint ("Io.netty.allocator.tinyCacheSize", 512);
Assigning from Tinysubpagepools
If there is no memory allocated in the above cache, the application will be tinysubpagepools to the memory pool, the main logic being:
 
 
  
  - Calculates the index of the Tinysubpagepools array, shifts to the right 4, divided by 16 (the array length is 512>>>4)
- Take out the index subpage, which is the head at index
- Find the right memory from Head.next
- Use io.netty.buffer.poolchunk#initbufwithsubpage after finding available memory (Io.netty.buffer.PooledByteBuf
Previously introduced Tinysubpagepools, is an array, the array size is 32, each element is a poolsubpage,poolsubpage itself is a linked list, so to find the available memory in this, first to calculate the array of the following table, Then find the location of the poolsubpage, take out the head of the list, and then allocate memory. The key code is as follows
Io.netty.buffer.poolarena#allocate (Io.netty.buffer.PoolThreadCache, Io.netty.buffer.pooledbytebuf<t>, int) private void allocate (Poolthreadcache cache, pooledbytebuf<t> buf, final int reqcapacity) {final int normcap    acity = normalizecapacity (reqcapacity);        if (Istinyorsmall (normcapacity)) {//capacity < pageSize int tableidx;        Poolsubpage<t>[] table;        Boolean tiny = Istiny (normcapacity);            if (tiny) {//< 512//Omit middle code ... tableidx = Tinyidx (normcapacity);        Table = Tinysubpagepools;        } else {//Omit intermediate code ...}        Final poolsubpage<t> head = Table[tableidx]; /** * Synchronize on the head. This is needed as {@link poolchunk#allocatesubpage (int.)} and * {@link poolchunk#free (long)} may modify the Dou             Bly linked list as well.            */synchronized (head) {final poolsubpage<t> s = head.next; Empty list words, heaD Point yourself if (s! = head) {assert S.donotdestroy && s.elemsize = = normcapacity;                Long handle = S.allocate ();                Assert handle >= 0;                S.chunk.initbufwithsubpage (buf, handle, reqcapacity);                Inctinysmallallocation (tiny);            Return }}//Omit intermediate code ...}
Why isn't there any memory available for Head.next?
The Tinysubpagepools store is a list of poolsubpage,poolsubpage that has been allocated part of the memory itself, if there are other poolsubpage in the list except head, Then this subpage must have a usable block of memory, because in poolsubpage.allocate, if there is no memory block available, the subpage will be removed from the list.
Assign according to normal mode
If neither of the above methods is allocated to memory, call the Allocatenormal method to allocate memory, and the method that Allocatenormal gets the memory has already been said before, and here is no longer a repeat.
Small memory allocation
The small allocation process is almost consistent with the tiny memory allocation process
Small memory allocation process:
 
 
  
  - If the tiny type is requested, the allocation is first attempted from the small cache and returned if the cache allocation succeeds 
- Otherwise, try assigning from Smallsubpagepools
- Use Allocatenormal to allocate if there are no assignments above 
The small memory acquisition process is similar to that of tiny, which can be compared with learning, and is no longer detailed here.
Netty Source code-six, tiny, small memory allocation