Netty - ByteBuf

suaxi
2026-07-08 / 0 评论 / 1 阅读 / 正在检测是否收录...
3.4 ByteBuf

(1)创建

// 创建一个池化基于直接内存的 ByteBuf(指定初始容量为16)
ByteBuf bf = ByteBufAllocator.DEFAULT.buffer(16);


(2)直接内存、堆内存

// 创建池化基于堆内存的 ByteBuf
ByteBuf bf = ByteBufAllocator.DEFAULT.heapBuffer(16);

// 创建池化基于直接内存的 ByteBuf
ByteBuf bf = ByteBufAllocator.DEFAULT.directBuffer(16);

堆内存:创建和销毁的成本很高,但读写性能好(少一次内存复制)

直接内存:不在 jvm 管辖范围内,GC 压力小


(3)池化、非池化

池化:可以重用 ByteBuf,高并发场景下更节约内存,能较少内存溢出的可能

非池化:每次使用时都得创建新的 ByteBuf 实例,且在堆内存、直接内存不同的场景下影响不同

Netty 4.1 后非 Android 平台默认开启池化


(4)组成

3.4ByteBuf组成.png


(5)写入

方法参数说明备注
writeBoolean(boolean value)写入 boolean 值一字节 01 表示 true、00 表示 false
writeByte(int value)写入 byte 值
writeShort(int value)写入 short 值
writeInt(int value)写入 int 值Big Endian,即 0x250,写入后 00 00 02 50(网络编程一般情况下默认使用大端写入)
writeIntLE(int value)写入 int 值Little Endian,即 0x250,写入后 50 02 00 00
writeLong(long value)写入 long 值
writeChar(int value)写入 char 值
writeFloat(float value)写入 float 值
writeDouble(double value)写入 double 值
writeBytes(ByteBuf src)写入 netty 的 ByteBuf
writeBytes(byte[] src)写入 byte[]
writeBytes(ByteBuffer src)写入 nio 的 ByteBuffer
int writeCharSequence(CharSequence sequence, Charset charset)写入字符串


演示:

package com.sw.netty._04;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;

public class ByteBufTest {
    public static void main(String[] args) {
        ByteBuf bf = ByteBufAllocator.DEFAULT.buffer(10);
        bf.writeBytes(new byte[]{1, 2, 3, 4});
        log(bf);
        // read index:0 write index:4 capacity:10
        //         +-------------------------------------------------+
        //         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
        // +--------+-------------------------------------------------+----------------+
        // |00000000| 01 02 03 04                                     |....            |
        // +--------+-------------------------------------------------+----------------+

        // 写入整型 10(4字节)
        bf.writeInt(10);
        log(bf);
        // read index:0 write index:8 capacity:10
        //         +-------------------------------------------------+
        //         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
        // +--------+-------------------------------------------------+----------------+
        // |00000000| 01 02 03 04 00 00 00 0a                         |........        |
        // +--------+-------------------------------------------------+----------------+
    }

    private static void log(ByteBuf buffer) {
        int length = buffer.readableBytes();
        int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
        StringBuilder buf = new StringBuilder(rows * 80 * 2)
                .append("read index:").append(buffer.readerIndex())
                .append(" write index:").append(buffer.writerIndex())
                .append(" capacity:").append(buffer.capacity())
                .append(NEWLINE);
        appendPrettyHexDump(buf, buffer);
        System.out.println(buf);
    }
}


(6)扩容

写入过程中,当 ByteBuf 容量不够时会进行扩容:

  • 如何写入后数据大小未超过 512,则选择下一个 16 的整数倍进行扩容,如:写入后大小为 12 ,则扩容后 capacity 是 16
  • 如果写入后数据大小超过 512,则选择下一个 2^n 进行扩容,如:写入后大小为 513,则扩容后 capacity 是 2^10=1024(2^9=512 已经不够了)
  • 扩容不能超过 max capacity 最大容量
package com.sw.netty._04;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;

public class ByteBufTest {
    public static void main(String[] args) {
        ByteBuf bf = ByteBufAllocator.DEFAULT.buffer(16);
        bf.writeBytes(new byte[]{1, 2, 3, 4});
        log(bf);
        // read index:0 write index:4 capacity:10
        //         +-------------------------------------------------+
        //         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
        // +--------+-------------------------------------------------+----------------+
        // |00000000| 01 02 03 04                                     |....            |
        // +--------+-------------------------------------------------+----------------+

        // 写入整型 10(4字节)
        bf.writeInt(10);
        log(bf);
        // read index:0 write index:8 capacity:10
        //         +-------------------------------------------------+
        //         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
        // +--------+-------------------------------------------------+----------------+
        // |00000000| 01 02 03 04 00 00 00 0a                         |........        |
        // +--------+-------------------------------------------------+----------------+

        // 继续写入(触发扩容)
        bf.writeBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9});
        log(bf);
        // read index:0 write index:17 capacity:64
        //         +-------------------------------------------------+
        //         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
        // +--------+-------------------------------------------------+----------------+
        // |00000000| 01 02 03 04 00 00 00 0a 01 02 03 04 05 06 07 08 |................|
        // |00000010| 09                                              |.               |
        // +--------+-------------------------------------------------+----------------+
    }

    private static void log(ByteBuf buffer) {
        int length = buffer.readableBytes();
        int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
        StringBuilder buf = new StringBuilder(rows * 80 * 2)
                .append("read index:").append(buffer.readerIndex())
                .append(" write index:").append(buffer.writerIndex())
                .append(" capacity:").append(buffer.capacity())
                .append(NEWLINE);
        appendPrettyHexDump(buf, buffer);
        System.out.println(buf);
    }
}
0

评论 (0)

取消