PooledByteBufAllocator的坑——不一定會池化

netty的PooledByteBufAllocator從名字上看就知道是使用池化內(nèi)存,但其實在一些場景是不一定使用池化的。

1 jvm內(nèi)存小于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參數(shù)

-Xmx50m -Xms50m

會發(fā)現(xiàn)一直沒爆內(nèi)存:


image.png

這個是為什么呢:
斷點的時候看到,根本就沒有從池里分配內(nèi)存


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);
        }
    }

使用參數(shù):

-Xmx200m -Xms200m 

發(fā)現(xiàn)內(nèi)存也是不會爆的。
這個是為什么呢,就是因為分配的內(nèi)存大于了16M
PoolArena類的allocateHuge方法是直接分配Unpooled的內(nèi)存的


image.png

為什么會走到allocateHuge呢?


image.png
16777216就是16M,所以是大于16M的時候就會這樣了。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容