diff --git "a/assets/\346\211\271\346\263\250 2020-07-07 105759.png" "b/assets/\346\211\271\346\263\250 2020-07-07 105759.png"
new file mode 100644
index 0000000000..b300e97cb4
Binary files /dev/null and "b/assets/\346\211\271\346\263\250 2020-07-07 105759.png" differ
diff --git "a/assets/\346\211\271\346\263\250 2020-07-07 110658.png" "b/assets/\346\211\271\346\263\250 2020-07-07 110658.png"
new file mode 100644
index 0000000000..788ee1593d
Binary files /dev/null and "b/assets/\346\211\271\346\263\250 2020-07-07 110658.png" differ
diff --git "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md" "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md"
index 24642bfcb9..d4a01c65b5 100644
--- "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md"
+++ "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/netty.md"
@@ -38,10 +38,6 @@ ChannelOption.SO_BACKLOG对应的是tcp/ip协议listen函数中的backlog参数
Channeloption.SO_KEEPALIVE参数对应于套接字选项中的SO_KEEPALIVE,该参数用于设置TCP连接,当设置该选项以后,连接会测试链接的状态,这个选项用于可能长时间没有数据交流的连接。当设置该选项以后,如果在两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
-### Unpooled类
-
-操作缓冲区的工具类
-
## 处理流式传输
数据通过网络传输,最终会缓存在一个字节数组里
diff --git "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md" "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md"
index 074cb40b3c..98fe7e76c6 100644
--- "a/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md"
+++ "b/\347\274\226\347\250\213\350\257\255\350\250\200/JAVA/\346\241\206\346\236\266/netty/\346\246\202\345\277\265\345\217\212\344\275\223\347\263\273\347\273\223\346\236\204.md"
@@ -251,4 +251,231 @@ Channel 是线程安全的
Embedded |
-
\ No newline at end of file
+
+
+## ByteBuf
+
+数据容器
+
+- 可以进行扩展
+- 零拷贝
+- 容量按需增长
+- 读写切换不需要调用flip
+- 读写使用不同索引
+- 方法链式调用
+- 引用计数
+- 池化
+
+![批注 2020-07-07 105759](/assets/批注%202020-07-07%20105759.png)
+
+### 使用模式
+
+- 堆缓冲区
+
+ByteBuf将数据存储在JVM的堆空间中
+
+```java
+ByteBuf heapBuf = ...;
+if (heapBuf.hasArray()) { ← -- 检查ByteBuf 是否有一个支撑数组
+ byte[] array = heapBuf.array(); ← -- 如果有,则获取对该数组的引用
+ int offset = heapBuf.arrayOffset() + heapBuf.readerIndex(); ← -- 计算第一个字节的偏移量。
+ int length = heapBuf.readableBytes(); ← -- 获得可读字节数
+ handleArray(array, offset, length); ← -- 使用数组、偏移量和长度作为参数调用你的方法
+}
+```
+
+- 直接缓冲区
+
+这种模式下的ByteBuf支持通过本地调用分配内存
+
+所以直接缓冲区的数据在堆外,不会被GC处理
+
+```java
+ByteBuf directBuf = ...;
+if (!directBuf.hasArray()) { ← -- 检查ByteBuf 是否由数组支撑。如果不是,则这是一个直接缓冲区
+ int length = directBuf.readableBytes(); ← -- 获取可读字节数
+ byte[] array = new byte[length]; ← -- 分配一个新的数组来保存具有该长度的字节数据
+ directBuf.getBytes(directBuf.readerIndex(), array); ← -- 将字节复制到该数组
+ handleArray(array, 0, length); ← -- 使用数组、偏移量和长度作为参数调用你的方法
+}
+```
+
+- 复合缓冲区
+
+这种模式下允许多个ByteBuf聚合起来,提供一个ByteBuf整体视图来进行操作
+
+### 字节级操作
+
+- 随机访问
+
+```java
+ByteBuf buffer = ...;
+for (int i = 0; i < buffer.capacity(); i++) {
+ byte b = buffer.getByte(i);
+ System.out.println((char)b);
+}
+```
+
+不会改变索引的值
+
+- 顺序访问
+
+![批注 2020-07-07 110658](/assets/批注%202020-07-07%20110658.png)
+
+调用discardReadBytes()可以回收可丢弃字节的空间
+
+读取所有数据
+
+```java
+ByteBuf buffer = ...;
+while (buffer.isReadable()) {
+ System.out.println(buffer.readByte());
+}
+```
+
+写入数据
+
+```java
+ByteBuf buffer = ...;
+while (buffer.writableBytes() >= 4) {
+ buffer.writeInt(random.nextInt());
+}
+```
+
+- 索引管理
+ - readerIndex(int):设置读索引位置
+ - writerIndex(int): 设置写索引位置
+ - clear():将读索引写索引重置为0
+
+- 查找
+
+```java
+// 查找回车符(\r)
+ByteBuf buffer = ...;
+int index = buffer.forEachByte(ByteBufProcessor.FIND_CR);
+```
+
+- 派生缓冲区
+
+ - duplicate()
+ - slice()
+ - slice(int, int)
+ - Unpooled.unmodifiableBuffer(…)
+ - order(ByteOrder)
+ - readSlice(int)
+ - copy()
+
+这些方法都会返回一个新的ByteBuf实例
+
+- 读/写
+ - get和set操作,从给定的索引开始,并且保持索引不变;
+ - read和write操作,从给定的索引开始,并且会根据已经访问过的字节数对索引进行调整。
+- 其他操作
+
+
+
+
+ 名 称 |
+ 描 述 |
+
+
+
+
+ isReadable() |
+ 如果至少有一个字节可供读取,则返回true |
+
+
+ isWritable() |
+ 如果至少有一个字节可被写入,则返回true |
+
+
+ readableBytes() |
+ 返回可被读取的字节数 |
+
+
+ writableBytes() |
+ 返回可被写入的字节数 |
+
+
+ capacity() |
+ 返回ByteBuf 可容纳的字节数。在此之后,它会尝试再次扩展直 到达到maxCapacity() |
+
+
+ maxCapacity() |
+ 返回ByteBuf 可以容纳的最大字节数 |
+
+
+ hasArray() |
+ 如果ByteBuf 由一个字节数组支撑,则返回true |
+
+
+ array() |
+ 如果 ByteBuf 由一个字节数组支撑则返回该数组;否则,它将抛出一个UnsupportedOperationException 异常 |
+
+
+
+
+### ByteBufHolder
+
+- 支持缓冲区池化
+ - 从池中复用ByteBuf
+
+
+
+
+ 名 称 |
+ 描 述 |
+
+
+
+
+ content() |
+ 返回由这个ByteBufHolder 所持有的ByteBuf |
+
+
+ copy() |
+ 返回这个ByteBufHolder 的一个深拷贝,包括一个其所包含的ByteBuf 的非共享副本 |
+
+
+ duplicate() |
+ 返回这个ByteBufHolder 的一个浅拷贝,包括一个其所包含的ByteBuf 的共享副本 |
+
+
+
+
+### ByteBuf分配
+
+**ByteBufAllocator**
+
+- 池化
+- buffer 返回基于对或者直接缓存存储
+- headBuffer 返回基于堆内存
+- directBuffer 返回基于直接内存
+- compositeBuffer
+- ioBuffer 返回套接字的IO操作buffer
+
+实现:
+
+- PooledByteBufAllocator
+ - 池化
+- UnpooledByteBufAllocator
+ - 每次调用都会返回一个新实例
+
+**Unpooled缓冲区**
+
+提供了一些静态方法来创建ByteBuf实例
+
+**ByteBufUtils**
+
+- hexdump 以16进制打印缓冲区
+- equals 比较两个ByteBuf
+
+### 引用计数
+
+ByteBuf 与 ByteBufHolder 都实现了引用计数
+
+```java
+boolean released = buffer.release(); ← -- 减少到该对象的活动引用。当减少到0 时,该对象被释放,并且该方法返回true
+```
+
+访问一个引用计数被释放的对象 会抛出异常
\ No newline at end of file