ByteBuf 源码分析

ByteBuf 的主要类继承关系

在这里插入图片描述

内存分配的角度来分类

1 堆内存字节(HeapByteBuf)缓冲区 :
内存的分配和回收的速度快,可以被JVM自动回收。 缺点是如果进行Socket的I/O读写,需要做一次额外的内存复制,将堆内存的缓冲区复制到Channel中,性能会下降。
2 直接内存(DirectByteBuf)
再堆外进行内存分配,分配和回收的速度慢一些,但是将它写入或者读取将直接在内核内存,减少一次内存复制,读写速度快。

那正是这样,最佳实践是再I/O通信的线程读写缓冲区使用DirectByteBuf ,后端业务消息使用HeapButeBuf,这样组合达到性能最优。

内存回收的角度来分类

基于对象池的ByteBuf和普通的ByteBuf 基于内存池的ByteBuf可以重用ByteBuf 对象,自己维护了一个内存池,可以循环利用ByteBuf对象,提升内存的使用效率,降低由于高负载导致的频繁GC,测试表明使用内存池可以在高负载,大并发的冲击下内存和gc更加平稳。

AbstactByteBuf 源码分析
在这里插入图片描述

readBtyes()

在这里插入图片描述
在这里插入图片描述

writeBytes()

在这里插入图片描述
在这里插入图片描述

写时扩容原理

采用了先倍增后步进的扩容方式,当内存小的时候,倍增不会造成太大的浪费 因此 到达某个阈值 需要进行步进式的扩容,这个阈值是个经验值,不同的应用场景,值是不同的,netty默认为4MB
重新计算动态扩张后,需要重新创建个新的缓冲区,将原来的缓冲区内容复制到新创建的ByteBuf里面,最后重新设置读写索引和mark标签
在这里插入图片描述

操作索引 mark

主要是获取 读写索引 mark 和set 比较简单

重用缓冲区discardReadBytes

主要是 discardReadBytes
1 首先要判断读索引是不是等于零,为零,就没有可重用的。2 如果大于零且读指针不等于写指针,说明已经存在被读取过的可以被遗弃的字节,3 也要调整mark的读写位置。

skipBytes

跳越过不需要读取的字节数。也要去判断要跳跃的字节数是否大于可读取的字节数

AbstractRefenceCountedByteBuf 的源码分析

从类的名字就知道 该类主要是对引用进行计数,类似于JVM内存回收的对象引用计数,用于跟踪对象的分配和销毁,做自动的内存回收

Byte的注意事项

注意ByteBuffer的自动释放 当继承不同的Handler 时 ,有的不会自动释放

不会自动释放的
在这里插入图片描述
会自动释放的
在这里插入图片描述在这里插入图片描述
在这里被释放掉 调用ReferenceCountUtil.release()

并发操作的问题

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值