Netty源码分析第五章: ByteBuf

第三节: 缓冲区分配器

缓冲区分配器, 顾明思议就是分配缓冲区的工具, 在netty中, 缓冲区分配器的顶级抽象是接口ByteBufAllocator, 里面定义了有关缓冲区分配的相关api

抽象类AbstractByteBufAllocator实现了ByteBufAllocator接口, 并且实现了其大部分功能

和AbstractByteBuf一样, AbstractByteBufAllocator也实现了缓冲区分配的骨架逻辑, 剩余的交给其子类

以其中的分配ByteBuf的方法为例, 对其做简单的介绍:

public ByteBuf buffer() {
if (directByDefault) {
return directBuffer();
}
return heapBuffer();
}

这里if (directByDefault)会判断默认创建的ByteBuf是不是一个基于直接内存的ByteBuf, 也就是direct类型的ByteBuf, 如果是, 则通过directBuffer()方法返回direct类型的ByteBuf, 否则, 会通过heapBuffer()返回heap类型的ByteBuf

跟到directBuffer()方法中:

public ByteBuf directBuffer() {
return directBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE);
}

这里又调用了一个重载directBuffer方法, 其中DEFAULT_INITIAL_CAPACITY代表分配的默认容量, Integer.MAX_VALUE表示分配的ByteBuf可扩容的最大容量, 也就是Integer类型的最大值, 我们再跟进去:

public ByteBuf directBuffer(int initialCapacity, int maxCapacity) {
if (initialCapacity == 0 && maxCapacity == 0) {
return emptyBuf;
}
validate(initialCapacity, maxCapacity);
return newDirectBuffer(initialCapacity, maxCapacity);
}

这里判断如果初始容量和最大容量都为0的话, 则返回一个emptyBuf的成员变量, emptyBuf代表一个空的ByteBuf

然后通过validate方法进行参数验证

最后newDirectBuffer创建一个Direct类型的ByteBuf, 并将初始容量和最大容量传入

在AbstractByteBufAllocator中, newDirectBuffer是一个抽象方法, 由其子类实现

protected abstract ByteBuf newDirectBuffer(int initialCapacity, int maxCapacity);

我们回到缓冲区分配的方法:

public ByteBuf buffer() {
if (directByDefault) {
return directBuffer();
}
return heapBuffer();
}

刚才简单剖析了directBuffer()的分配, 现在在继续跟到heapBuffer()中, 看其分配heap类型的ByteBuf的抽象逻辑:

public ByteBuf heapBuffer() {
return heapBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE);
}

这里同样调用了重载的heapBuffer, 并传入了初始容量和最大容量

再继续跟heapBuffer方法:

public ByteBuf heapBuffer(int initialCapacity, int maxCapacity) {
if (initialCapacity == 0 && maxCapacity == 0) {
return emptyBuf;
}
validate(initialCapacity, maxCapacity);
return newHeapBuffer(initialCapacity, maxCapacity);
}

同样, 这里如果初始容量和最大容量都为空的话, 返回一个代表空的ByteBuf

然后通过validate方法进行参数验证

最后通过newHeapBuffer方法创建一个新的heap类型的ByteBuf

同样, newHeapBuffer方法在AbstractByteBufAllocator中也是一个抽象方法, 具体逻辑交给其子类实现

protected abstract ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity);

newDirectBuffer和newHeapBuffer两个抽象方法中, 在其子类PooledByteBufAllocator和UnpooledByteBufAllocator中都有实现

我们以UnpooledByteBufAllocator的newHeapBuffer方法为例, 看其实现:

protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
return PlatformDependent.hasUnsafe() ? new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity)
: new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
}

里实现方式其实很简单, 首先通过PlatformDependent.hasUnsafe()判断当前运行环境是否能创建unsafe对象, 如果能, 则直接通过new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity)方式创建一个UnpooledUnsafeHeapByteBuf对象, 也就是一个Unsafe的ByteBuf对象

如果当前环境不能创建unsafe对象, 则通过new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity)这种方方式创建一个UnpooledHeapByteBuf对象, 也就是非Unsafe的ByteBuf对象

从这里能看出, 其实在创建ByteBuf对象时, 是否创建unsafe类型的对象并不是我们自己控制的, 而是通过程序判断当前环境来决定是否创建unsafe类型的ByteBuf对象的

有关ByteBufAllocator的继承关系如下:

5-3-1

上一节: ByteBuf的分类

下一节: PooledByteBufAllocator简述

Netty源码分析第5章(ByteBuf)---->第3节: 缓冲区分配器的更多相关文章

  1. Netty源码分析第5章(ByteBuf)---->第4节: PooledByteBufAllocator简述

    Netty源码分析第五章: ByteBuf 第四节: PooledByteBufAllocator简述 上一小节简单介绍了ByteBufAllocator以及其子类UnPooledByteBufAll ...

  2. Netty源码分析第5章(ByteBuf)---->第5节: directArena分配缓冲区概述

    Netty源码分析第五章: ByteBuf 第五节: directArena分配缓冲区概述 上一小节简单分析了PooledByteBufAllocator中, 线程局部缓存和arean的相关逻辑, 这 ...

  3. Netty源码分析第5章(ByteBuf)---->第6节: 命中缓存的分配

    Netty源码分析第6章: ByteBuf 第六节: 命中缓存的分配 上一小节简单分析了directArena内存分配大概流程, 知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带 ...

  4. Netty源码分析第5章(ByteBuf)---->第7节: page级别的内存分配

    Netty源码分析第五章: ByteBuf 第六节: page级别的内存分配 前面小节我们剖析过命中缓存的内存分配逻辑, 前提是如果缓存中有数据, 那么缓存中没有数据, netty是如何开辟一块内存进 ...

  5. Netty源码分析第5章(ByteBuf)---->第10节: SocketChannel读取数据过程

    Netty源码分析第五章: ByteBuf 第十节: SocketChannel读取数据过程 我们第三章分析过客户端接入的流程, 这一小节带大家剖析客户端发送数据, Server读取数据的流程: 首先 ...

  6. Netty源码分析第5章(ByteBuf)---->第1节: AbstractByteBuf

    Netty源码分析第五章: ByteBuf 概述: 熟悉Nio的小伙伴应该对jdk底层byteBuffer不会陌生, 也就是字节缓冲区, 主要用于对网络底层io进行读写, 当channel中有数据时, ...

  7. Netty源码分析第5章(ByteBuf)---->第2节: ByteBuf的分类

    Netty源码分析第五章: ByteBuf 第二节: ByteBuf的分类 上一小节简单介绍了AbstractByteBuf这个抽象类, 这一小节对其子类的分类做一个简单的介绍 ByteBuf根据不同 ...

  8. Netty源码分析第5章(ByteBuf)---->第8节: subPage级别的内存分配

    Netty源码分析第五章: ByteBuf 第八节: subPage级别的内存分配 上一小节我们剖析了page级别的内存分配逻辑, 这一小节带大家剖析有关subPage级别的内存分配 通过之前的学习我 ...

  9. Netty源码分析第5章(ByteBuf)---->第9节: ByteBuf回收

    Netty源码分析第五章: ByteBuf 第九节: ByteBuf回收 之前的章节我们提到过, 堆外内存是不受jvm垃圾回收机制控制的, 所以我们分配一块堆外内存进行ByteBuf操作时, 使用完毕 ...

随机推荐

  1. 1003. [ZJOI2006]物流运输【区间DP+最短路】

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转 停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严 ...

  2. django操作多数据库

    django操作多数据库 1.    添加数据库路由分配文件 在项目文件夹里创建‘database_router’文件.将下面的代码复制到该文件里. from django.conf import s ...

  3. Hive学习之路 (二十)Hive 执行过程实例分析

    一.Hive 执行过程概述 1.概述 (1) Hive 将 HQL 转换成一组操作符(Operator),比如 GroupByOperator, JoinOperator 等 (2)操作符 Opera ...

  4. Hive学习之路 (十六)Hive分析窗口函数(四) LAG、LEAD、FIRST_VALUE和LAST_VALUE

    数据准备 数据格式 cookie4.txt cookie1, ::,url2 cookie1, ::,url1 cookie1, ::,1url3 cookie1, ::,url6 cookie1, ...

  5. Kafka设计解析(八)Exactly Once语义与事务机制原理

    转载自 技术世界,原文链接 Kafka设计解析(八)- Exactly Once语义与事务机制原理 本文介绍了Kafka实现事务性的几个阶段——正好一次语义与原子操作.之后详细分析了Kafka事务机制 ...

  6. 469 B. Intercepted Message

    http://codeforces.com/problemset/problem/950/B Hacker Zhorik wants to decipher two secret messages h ...

  7. start_kernel之前的汇编代码分析

    start_kernel之前的汇编代码分析 Boot中执行下面两句话之后,进入uclinux内核. theKernel = (void (*)(int, int, unsigned int))((ui ...

  8. 实现Redis Cluster并实现Python链接集群

    目录 一.Redis Cluster简单介绍 二.背景 三.环境准备 3.1 主机环境 3.2 主机规划 四.部署Redis 4.1 安装Redis软件 4.2 编辑Redis配置文件 4.3 启动R ...

  9. 文字属性和div容器盒的使用基础

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. centos下安装myrocksdb

    承接上一篇,https://www.cnblogs.com/lunyu/p/10190364.html .编译安装myrocks的整个过程,特别是第2步和第7步,让人冗长难耐.因此编译安装成功后省去这 ...