• Netty内存池源码一 (内存分配入口)


    Netty-内存池源码一 (内存分配入口)

    当 Client 向 Server 发送请求, 此时Server端的 【NioSocketChannel】 则会响应 【readOps】 事件。而在处理该事件时, 需要使用ByteBuf , 那么目标就指向:

    AbstractNioByteChannel #NioByteUnsafe # read()

    public final void read() {
    
        //.....省略
    
        // #1. 获取  池化内存缓冲区分配器
        final ByteBufAllocator allocator = config.getAllocator();
    
        // #2. 获取  缓冲区大小预测器
        final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
    
        ByteBuf byteBuf = null;
        boolean close = false;
        try {
            do {
                
                //#3. 分配出一块内存 byteBuf
                byteBuf = allocHandle.allocate(allocator);
               
            } while (allocHandle.continueReading());
    
        }  // .....省略
    }
    

    从代码看 allocator 就是 分配Netty 用来分配内存的大佬, 那么 该池化内存缓冲区分配器是谁?

    1. #1 final ByteBufAllocator allocator = config.getAllocator();

      跟随 config.getAllocator() 可知,该allocator 是由 【ByteBufUtil】工具类获取的,代码如下

      ByteBufAllocator allocator = ByteBufUtil.DEFAULT_ALLOCATOR;

      进入【ByteBufUtil】, 其中有段关键的代码

           
      	// 当前平台若是Android 内存分配器则使用 unpooled,  若不是则使用 pooled
      	String allocType = SystemPropertyUtil.get(
                      "io.netty.allocator.type", PlatformDependent.isAndroid() ? "unpooled" : "pooled");
      
      
              ByteBufAllocator alloc;
              if ("unpooled".equals(allocType)) {
                  alloc = UnpooledByteBufAllocator.DEFAULT;
                  logger.debug("-Dio.netty.allocator.type: {}", allocType);
              } else if ("pooled".equals(allocType)) {
                  
                  // 默认会使用 该内存分配器 PooledByteBufAllocator
                  alloc = PooledByteBufAllocator.DEFAULT;
                  logger.debug("-Dio.netty.allocator.type: {}", allocType);
              } else {
                  alloc = PooledByteBufAllocator.DEFAULT;
                  logger.debug("-Dio.netty.allocator.type: pooled (unknown: {})", allocType);
              }
      
              DEFAULT_ALLOCATOR = alloc;
      

      从上面代码可知, 默认普通情况下 内存分配器就是 【PooledByteBufAllocator

    2. #3 byteBuf = allocHandle.allocate(allocator); 下面跟踪该分配方法:

      => 1.【DefaultMaxMessagesRecvByteBufAllocator #MaxMessageHandle #allocate()】: alloc.ioBuffer(guess());

      => 2.【AbstractByteBufAllocator #ioBuffer()】: directBuffer(initialCapacity); 这里我们默认使用直接内存。

      => 3. 【AbstractByteBufAllocator #directBuffer()】:

      newDirectBuffer(initialCapacity, maxCapacity);

      => 4. 最终会来到 PooledByteBufAllocator #newDirectBuffer() 该方法就是申请分配内存的入口

    万般皆下品,唯有读书高!
  • 相关阅读:
    Linux下设置 Tomcat JDK MySQL运用平台
    引见在Linux把持细碎下装置Tomcat的要领
    在linux下的freetds装置体式款式
    介绍两款超级小的linux,可以安排在u盘里玩
    在Debian环境下架设PPPoE效劳器2
    GRUB2 指导按次的开展目标
    Linux下设置配备布置服从完美的Web效力器
    Ubuntu Linux体系创设FTP办事器装备步调
    高效运用Linux的七个好习气2
    Ubuntu Linux 8.04零碎JAVA环境设置装备陈设体式格式
  • 原文地址:https://www.cnblogs.com/s686zhou/p/15695617.html
Copyright © 2020-2023  润新知