本文基于 Netty 4.1.112.Final 版本進(jìn)行討論
本來(lái)筆者是想在上篇文章 《談一談 Netty 的內(nèi)存管理 —— 且看 Netty 如何實(shí)現(xiàn) Java 版的 Jemalloc》 中的最后一個(gè)小節(jié)芒划,介紹一下 Netty 內(nèi)存池所提供的所有 Metrics 举娩, 從內(nèi)存池監(jiān)控的角度為文章收一個(gè)尾,沒(méi)想到字?jǐn)?shù)超過(guò)了公眾號(hào)的限制,只能將最后一個(gè)小節(jié)刪除吆你,現(xiàn)在來(lái)把最后一個(gè)小節(jié)來(lái)給大家補(bǔ)上。
3.png
9. 內(nèi)存池相關(guān)的 Metrics
為了更好的監(jiān)控內(nèi)存池的運(yùn)行狀態(tài)肉微,Netty 為內(nèi)存池中的每個(gè)組件都設(shè)計(jì)了一個(gè)對(duì)應(yīng)的 Metrics 類,用于封裝與該組件相關(guān)的 Metrics遵馆。
image.png
其中內(nèi)存池 PooledByteBufAllocator 提供的 Metrics 如下:
public final class PooledByteBufAllocatorMetric implements ByteBufAllocatorMetric {
private final PooledByteBufAllocator allocator;
PooledByteBufAllocatorMetric(PooledByteBufAllocator allocator) {
this.allocator = allocator;
}
// 內(nèi)存池一共有多少個(gè) PoolArenas
public int numDirectArenas() {
return allocator.numDirectArenas();
}
// 內(nèi)存池中一共綁定了多少線程
public int numThreadLocalCaches() {
return allocator.numThreadLocalCaches();
}
// 每一種 Small 規(guī)格最大可緩存的個(gè)數(shù),默認(rèn)為 256
public int smallCacheSize() {
return allocator.smallCacheSize();
}
// 每一種 Normal 規(guī)格最大可緩存的個(gè)數(shù)丰榴,默認(rèn)為 64
public int normalCacheSize() {
return allocator.normalCacheSize();
}
// 內(nèi)存池中 PoolChunk 的尺寸大小货邓,默認(rèn)為 4M
public int chunkSize() {
return allocator.chunkSize();
}
// 該內(nèi)存池目前一共向 OS 申請(qǐng)了多少內(nèi)存(包括 Huge 規(guī)格)單位為字節(jié)
@Override
public long usedDirectMemory() {
return allocator.usedDirectMemory();
}
PoolArena 提供的 Metrics 如下:
abstract class PoolArena<T> implements PoolArenaMetric {
// 一共有多少線程與該 PoolArena 進(jìn)行綁定
@Override
public int numThreadCaches() {
return numThreadCaches.get();
}
// 一共有多少種 Small 規(guī)格尺寸,默認(rèn)為 39
@Override
public int numSmallSubpages() {
return smallSubpagePools.length;
}
// 該 PoolArena 中一共包含了幾個(gè) PoolChunkList
@Override
public int numChunkLists() {
return chunkListMetrics.size();
}
// 該 PoolArena 總共分配內(nèi)存塊的次數(shù)(包含 Small 規(guī)格四濒,Normal 規(guī)格换况,Huge 規(guī)格)
// 一直累加,內(nèi)存塊釋放不遞減
long numAllocations();
// PoolArena 總共分配 Small 規(guī)格的次數(shù)盗蟆,一直累加复隆,釋放不遞減
long numSmallAllocations();
// PoolArena 總共分配 Normal 規(guī)格的次數(shù),一直累加姆涩,釋放不遞減
long numNormalAllocations();
// PoolArena 總共分配 Huge 規(guī)格的次數(shù)挽拂,一直累加,釋放不遞減
long numHugeAllocations();
// 該 PoolArena 總共回收內(nèi)存塊的次數(shù)(包含 Small 規(guī)格骨饿,Normal 規(guī)格亏栈,Huge 規(guī)格)
// 一直累加
long numDeallocations();
// PoolArena 總共回收 Small 規(guī)格的次數(shù),一直累加
long numSmallDeallocations();
// PoolArena 總共回收 Normal 規(guī)格的次數(shù)宏赘,一直累加
long numNormalDeallocations();
// PoolArena 總共釋放 Huge 規(guī)格的次數(shù)绒北,一直累加
long numHugeDeallocations();
// PoolArena 當(dāng)前凈內(nèi)存分配次數(shù)
// 總 Allocations 計(jì)數(shù)減去總 Deallocations 計(jì)數(shù)
long numActiveAllocations();
// 同理,PoolArena 對(duì)應(yīng)規(guī)格的凈內(nèi)存分配次數(shù)
long numActiveSmallAllocations();
long numActiveNormalAllocations();
long numActiveHugeAllocations();
// 該 PoolArena 目前一共向 OS 申請(qǐng)了多少內(nèi)存(包括 Huge 規(guī)格)單位為字節(jié)
long numActiveBytes();
}
PoolSubpage 提供的 Metrics 如下:
final class PoolSubpage<T> implements PoolSubpageMetric {
// 該 PoolSubpage 一共可以切分出多少個(gè)對(duì)應(yīng) Small 規(guī)格的內(nèi)存塊
@Override
public int maxNumElements() {
return maxNumElems;
}
// 該 PoolSubpage 當(dāng)前還剩余多少個(gè)未分配的內(nèi)存塊
int numAvailable();
// PoolSubpage 管理的 Small 規(guī)格尺寸
int elementSize();
// 內(nèi)存池的 pageSize察署,默認(rèn)為 8K
int pageSize();
}
PoolChunkList 提供的 Metrics 如下:
final class PoolChunkList<T> implements PoolChunkListMetric {
// 該 PoolChunkList 中管理的 PoolChunk 內(nèi)存使用率下限闷游,單位百分比
@Override
public int minUsage() {
return minUsage0(minUsage);
}
// 該 PoolChunkList 中管理的 PoolChunk 內(nèi)存使用率上限,單位百分比
@Override
public int maxUsage() {
return min(maxUsage, 100);
}
}
PoolChunk 提供的 Metrics 如下:
final class PoolChunk<T> implements PoolChunkMetric {
// 當(dāng)前 PoolChunk 的內(nèi)存使用率贴汪,單位百分比
int usage();
// 默認(rèn) 4M
int chunkSize();
// 當(dāng)前 PoolChunk 中剩余內(nèi)存容量脐往,單位字節(jié)
int freeBytes();
}