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. 在myeclipse的工作环境上配置默认编码为UTF-8

        将默认环境转为UTF-8,看图分析: 在windows->Preferences上 这样整个环境就变成UTF-8,只是这样还不够, 还须要,假设你须要所有文件都设为UTF-8,就: wa ...

  2. 1087. [SCOI2005]互不侵犯King【状压DP】

    Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行, ...

  3. Java实现数据库操作

    Java实现数据库操作 这里的样例是使用mysql数据库 代码实现 /* MySQLHelper.java */ import java.io.*; import java.util.*; impor ...

  4. c++版 nms

    目前这个代码运行会报一些错误,还要再修改修改才行 #include<iostream> #include<vector> #include<algorithm> # ...

  5. pip问题解决方案

    错误信息:usr/bin/pip: No such file or directory 解决办法(一共四步,按照下面的步骤来从1到4,最后你会发现问题都解决了): 1.which pip /usr/l ...

  6. Struts2 的ActionContext 详解

    转自:http://www.cnblogs.com/shaohz2014/p/3962779.html ActionContext是Action的上下文,Struts2自动在其中保存了一些在Actio ...

  7. java面向对象之个人总结

    面向对象有三大特性:继承,封装,多态 1.继承: (1)继承的特点:A,java支持单根继承,不支持多根继承 B,java支持多层继承(继承体系) (2)细节注意:A.子类只能继承父类的非私有成员(成 ...

  8. TFTP服务的搭建

    TFTP服务的作用:提供网络下载服务 tftp服务器的安装与配置: tftp主要用于嵌入式交叉开发环境的搭建,传输文件. 0.创建tftp的工作目录,并修改权限(注意:请在主目录下创建此工作目录!) ...

  9. Apache 流框架 Flink,Spark Streaming,Storm对比分析(二)

    本文由  网易云发布. 本文内容接上一篇Apache 流框架 Flink,Spark Streaming,Storm对比分析(一) 2.Spark Streaming架构及特性分析 2.1 基本架构 ...

  10. 版本管理工具git与svn简介

    版本管理工具 版本管理工具简介 常见版本管理工具 cvs(Concurrent Versions System) vss(Visual SourceSafe) svn 常用的版本管理工具 git 流行 ...