netty的PooledByteBufAllocator从名字上看就知道是使用池化内存,但其实在一些场景是不一定使用池化的。
1 jvm内存小于96M的时候,是不会使用池的
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参数
-Xmx50m -Xms50m
会发现一直没爆内存:
image.png
这个是为什么呢:
断点的时候看到,根本就没有从池里分配内存
image.png
heapArena为什么是null呢?
是因为nHeapArena为0
image.png
nHeapArena是由DEFAULT_NUM_HEAP_ARENA决定的
image.png
核心逻辑是:
runtime.maxMemory() / defaultChunkSize / 2 / 3
defaultChunkSize 是16777216,就是16M
16Mx2x3=96M,也就是说 runtime.maxMemory()大于96M的时候,才会用到池化。
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);
}
}
使用参数:
-Xmx200m -Xms200m
发现内存也是不会爆的。
这个是为什么呢,就是因为分配的内存大于了16M
PoolArena类的allocateHuge方法是直接分配Unpooled的内存的
image.png
为什么会走到allocateHuge呢?
image.png
网友评论