netty的PooledByteBufAllocator從名字上看就知道是使用池化內(nèi)存真朗,但其實(shí)在一些場景是不一定使用池化的逾冬。
1 jvm內(nèi)存小于96M的時(shí)候看疙,是不會使用池的
public static void main(String[] args) throws Exception {
ByteBufAllocator byteBufAllocator = new PooledByteBufAllocator(false);
for (int i = 0; i < 1000; i++) {
ByteBuf buffer = byteBufAllocator.heapBuffer(1 * 1024 * 1024);
System.out.println("分配了 " + 1 * (i + 1) + " MB");
Thread.sleep(30);
}
}
使用jvm參數(shù)
-Xmx50m -Xms50m
會發(fā)現(xiàn)一直沒爆內(nèi)存:
這個(gè)是為什么呢:
斷點(diǎn)的時(shí)候看到畦浓,根本就沒有從池里分配內(nèi)存
heapArena為什么是null呢宴倍?
是因?yàn)閚HeapArena為0
nHeapArena是由DEFAULT_NUM_HEAP_ARENA決定的
核心邏輯是:
runtime.maxMemory() / defaultChunkSize / 2 / 3
defaultChunkSize 是16777216张症,就是16M
16Mx2x3=96M,也就是說 runtime.maxMemory()大于96M的時(shí)候鸵贬,才會用到池化俗他。
2 如果對象大于16M,也是不會使用池的
public static void main(String[] args) throws Exception {
ByteBufAllocator byteBufAllocator = new PooledByteBufAllocator(false);
for (int i = 0; i < 1000; i++) {
ByteBuf buffer = byteBufAllocator.heapBuffer(20 * 1024 * 1024);
System.out.println("分配了 " + 20 * (i + 1) + " MB");
Thread.sleep(30);
}
}
使用參數(shù):
-Xmx200m -Xms200m
發(fā)現(xiàn)內(nèi)存也是不會爆的阔逼。
這個(gè)是為什么呢兆衅,就是因?yàn)榉峙涞膬?nèi)存大于了16M
PoolArena類的allocateHuge方法是直接分配Unpooled的內(nèi)存的
為什么會走到allocateHuge呢?