Unlocking Netty’s Memory Pool Metrics: A Deep Dive into PooledByteBufAllocator

This article adds a missing section on Netty 4.1.112.Final memory pool metrics, detailing the various Metrics classes for PooledByteBufAllocator, PoolArena, PoolSubpage, PoolChunkList, and PoolChunk, and includes code examples for each.

Bin's Tech Cabin
Bin's Tech Cabin
Bin's Tech Cabin
Unlocking Netty’s Memory Pool Metrics: A Deep Dive into PooledByteBufAllocator

This article, based on Netty 4.1.112.Final, adds a previously omitted section that explains the memory‑pool related Metrics Netty provides for monitoring its internal components.

9. Memory Pool Metrics

To better monitor the memory pool’s runtime state, Netty defines a Metrics class for each component of the pool.

The PooledByteBufAllocator provides the following Metrics:

public final class PooledByteBufAllocatorMetric implements ByteBufAllocatorMetric {
    private final PooledByteBufAllocator allocator;
    PooledByteBufAllocatorMetric(PooledByteBufAllocator allocator) {
        this.allocator = allocator;
    }
    // Number of PoolArenas
    public int numDirectArenas() {
        return allocator.numDirectArenas();
    }
    // Number of thread‑local caches bound to the pool
    public int numThreadLocalCaches() {
        return allocator.numThreadLocalCaches();
    }
    // Max cache size for Small allocations (default 256)
    public int smallCacheSize() {
        return allocator.smallCacheSize();
    }
    // Max cache size for Normal allocations (default 64)
    public int normalCacheSize() {
        return allocator.normalCacheSize();
    }
    // Size of each PoolChunk, default 4M
    public int chunkSize() {
        return allocator.chunkSize();
    }
    // Total direct memory requested from OS (bytes)
    @Override
    public long usedDirectMemory() {
        return allocator.usedDirectMemory();
    }
}

Metrics provided by PoolArena:

abstract class PoolArena<T> implements PoolArenaMetric {
    // Number of thread caches bound to this PoolArena
    @Override
    public int numThreadCaches() {
        return numThreadCaches.get();
    }
    // Number of Small subpage sizes, default 39
    @Override
    public int numSmallSubpages() {
        return smallSubpagePools.length;
    }
    // Number of PoolChunkLists managed by this PoolArena
    @Override
    public int numChunkLists() {
        return chunkListMetrics.size();
    }
    // Total allocation count (all sizes)
    long numAllocations();
    // Allocation count for Small size
    long numSmallAllocations();
    // Allocation count for Normal size
    long numNormalAllocations();
    // Allocation count for Huge size
    long numHugeAllocations();
    // Total deallocation count
    long numDeallocations();
    // Deallocation count for Small size
    long numSmallDeallocations();
    // Deallocation count for Normal size
    long numNormalDeallocations();
    // Deallocation count for Huge size
    long numHugeDeallocations();
    // Net active allocation count (allocations – deallocations)
    long numActiveAllocations();
    // Net active allocation count for Small size
    long numActiveSmallAllocations();
    // Net active allocation count for Normal size
    long numActiveNormalAllocations();
    // Net active allocation count for Huge size
    long numActiveHugeAllocations();
    // Total bytes requested from OS by this PoolArena
    long numActiveBytes();
}

Metrics provided by PoolSubpage:

final class PoolSubpage<T> implements PoolSubpageMetric {
    // Maximum number of Small elements this subpage can split
    @Override
    public int maxNumElements() {
        return maxNumElems;
    }
    // Number of available (unallocated) elements
    int numAvailable();
    // Size of each element
    int elementSize();
    // Page size, default 8K
    int pageSize();
}

Metrics provided by PoolChunkList:

final class PoolChunkList<T> implements PoolChunkListMetric {
    // Minimum usage percentage for PoolChunks in this list
    @Override
    public int minUsage() {
        return minUsage0(minUsage);
    }
    // Maximum usage percentage for PoolChunks in this list
    @Override
    public int maxUsage() {
        return Math.min(maxUsage, 100);
    }
}

Metrics provided by PoolChunk:

final class PoolChunk<T> implements PoolChunkMetric {
    // Current usage percentage of this chunk
    int usage();
    // Chunk size, default 4M
    int chunkSize();
    // Remaining free bytes in this chunk
    int freeBytes();
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

backend-developmentmemory pool
Bin's Tech Cabin
Written by

Bin's Tech Cabin

Original articles dissecting source code and sharing personal tech insights. A modest space for serious discussion, free from noise and bureaucracy.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.