Java最新Netty 源码分析系列(七)字节缓冲区 ByteBuf(下),价值2000元的Java学习资源泄露

最后

学习视频:

大厂面试真题:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

image-20210811130551547

在读取之后,索引 0 到 readIndex位置的区域被视为废弃字节(discard)。可以调用discardReadBytes方法,来释放这部分空间,其作用类似于 ByteBuffercompact()方法,移除无用的数据,实现缓冲区的重复利用。如下图,展示了执行discardReadBytes后的情况,相当于可写的空间变大了。

image-20210811130822648

ByteBuf 的使用案例


为了更好的理解ByteBuf,编写了以下示例:

public class ByteBufDemo {

/**

  • @param args

*/

public static void main(String[] args) {

// 创建一个缓冲区

ByteBuf buffer = Unpooled.buffer(10);

System.out.println(“------------初始时缓冲区------------”);

printBuffer(buffer);

// 添加一些数据到缓冲区中

System.out.println(“------------添加数据到缓冲区------------”);

String s = “love”;

buffer.writeBytes(s.getBytes());

printBuffer(buffer);

// 读取数据

System.out.println(“------------读取数据------------”);

while (buffer.isReadable()) {

System.out.println(buffer.readByte());

}

printBuffer(buffer);

// 执行compact

System.out.println(“------------执行discardReadBytes------------”);

buffer.discardReadBytes();

printBuffer(buffer);

// 执行clear

System.out.println(“------------执行clear清空缓冲区------------”);

buffer.clear();

printBuffer(buffer);

}

/**

  • 打印出ByteBuf的信息

  • @param buffer

*/

private static void printBuffer(ByteBuf buffer) {

System.out.println(“readerIndex:” + buffer.readerIndex());

System.out.println(“writerIndex:” + buffer.writerIndex());

System.out.println(“capacity:” + buffer.capacity());

}

}

复制代码

输出结果:

------------初始时缓冲区------------

readerIndex:0

writerIndex:0

capacity:10

------------添加数据到缓冲区------------

readerIndex:0

writerIndex:4

capacity:10

------------读取数据------------

108

111

118

101

readerIndex:4

writerIndex:4

capacity:10

------------执行discardReadBytes------------

readerIndex:0

writerIndex:0

capacity:10

------------执行clear清空缓冲区------------

readerIndex:0

writerIndex:0

capacity:10

Process finished with exit code 0

复制代码

对比ByteBufferByteBuf两个示例可以看出,Netty 提供了更加方便地创建ByteBuf的工具(unpooled),同时,也不必再执行flip()方法来切换读写模式。对比而言,ByteBuf更加易于使用。

ByteBuf 的3种使用模式


ByteBuf 共有三种使用模式:堆缓冲区模式(Heap Buffer)、直接缓冲区模式(Direct Buffer)和 复合缓冲区模式(Composite Buffer)。

堆缓冲模式

堆缓冲区模式又称为支撑数组,其数据是存放在JVM的堆空间,通过将数据存储在数组中实现。

优点:数据存储在JVM堆中可以快速的创建和快速释放,并且提供了数据快速访问的方法;

缺点:每次数据与 I/O 进行传输时,都需要将数据复制到直接缓冲区。

以下是堆缓冲区的代码示例:

public class ByteBufHeapBufferDemo {

/**

  • @param args

*/

public static void main(String[] args) {

// 创建一个堆缓冲区

ByteBuf buffer = Unpooled.buffer(10);

String s = “waylau”;

buffer.writeBytes(s.getBytes());

// 检查是否是支撑数组

if (buffer.hasArray()) {

// 获取支撑数组的引用

byte[] array = buffer.array();

// 计算第一个字节的偏移量

int offset = buffer.readerIndex() + buffer.arrayOffset();

// 可读字节数

int length = buffer.readableBytes();

printBuffer(array, offset, length);

}

}

/**

  • 打印出Buffer的信息

  • @param buffer

*/

private static void printBuffer(byte[] array, int offset, int len) {

System.out.println(“array:” + array);

System.out.println(“array->String:” + new String(array));

System.out.println(“offset:” + offset);

System.out.println(“len:” + len);

}

}

复制代码

输出结果:

array:[B@5b37e0d2

array->String:waylau

offset:0

len:6

Process finished with exit code 0

复制代码

直接缓冲区模式

直接缓冲区属于堆外分配的直接内存,不会占用堆得空间。

优点:使用 socket 传输数据时性能很好,避免了数据从 JVM 堆内存复制到直接缓冲区的过程,提高了性能。

缺点:相对于堆缓冲区而言,直接缓冲区分配内存空间和释放更为昂贵。

对于涉及大量的 I/O 数据的读写,建议使用直接缓冲区。而对于用于后端业务消息编解码模块,建议使用堆缓冲区。

以下是直接缓冲区代码示例:

public class ByteBufDirectBufferDemo {

/**

  • @param args

*/

public static void main(String[] args) {

// 创建一个直接缓冲区

ByteBuf buffer = Unpooled.directBuffer(10);

String s = “waylau”;

buffer.writeBytes(s.getBytes());

// 检查是否是支撑数组.

// 不是支撑数组,则为直接缓冲区

if (!buffer.hasArray()) {

// 计算第一个字节的偏移量

int offset = buffer.readerIndex();

// 可读字节数

int length = buffer.readableBytes();

// 获取字节内容

byte[] array = new byte[length];

buffer.getBytes(offset, array);

printBuffer(array, offset, length);

}

}

/**

  • 打印出Buffer的信息

  • @param buffer

*/

private static void printBuffer(byte[] array, int offset, int len) {

总结:心得体会

既然选择这个行业,选择了做一个程序员,也就明白只有不断学习,积累实战经验才有资格往上走,拿高薪,为自己,为父母,为以后的家能有一定的经济保障。

学习时间都是自己挤出来的,短时间或许很难看到效果,一旦坚持下来了,必然会有所改变。不如好好想想自己为什么想进入这个行业,给自己内心一个答案。

面试大厂,最重要的就是夯实的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

的基础,不然面试官随便一问你就凉了;其次会问一些技术原理,还会看你对知识掌握的广度,最重要的还是你的思路,这是面试官比较看重的。

最后,上面这些大厂面试真题都是非常好的学习资料,通过这些面试真题能够看看自己对技术知识掌握的大概情况,从而能够给自己定一个学习方向。包括上面分享到的学习指南,你都可以从学习指南里理顺学习路线,避免低效学习。

大厂Java架构核心笔记(适合中高级程序员阅读):

[外链图片转存中…(img-VTHYHJSF-1715409446576)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值