美文网首页
PooledByteBufAllocator的坑——不一定会池化

PooledByteBufAllocator的坑——不一定会池化

作者: 黄云斌huangyunbin | 来源:发表于2019-04-28 18:54 被阅读0次

    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
    16777216就是16M,所以是大于16M的时候就会这样了。

    相关文章

      网友评论

          本文标题:PooledByteBufAllocator的坑——不一定会池化

          本文链接:https://www.haomeiwen.com/subject/axmjnqtx.html