Netty 的零拷贝实现?

Johngo学长 Netty 40

Netty 的接收和发送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接内 存进行 Socket 读写,不需要进行字节缓冲区的二次拷贝。堆内存多了一次内 存拷贝,JVM 会将堆内存 Buffer 拷贝一份到直接内存中,然后才写入Socket 中。ByteBuffer 由 ChannelConfig 分配,而 ChannelConfig 创建 ByteBufAllocator 默认使用 Direct Buffer。

CompositeByteBuf 类可以将多个 ByteBuf 合并为一个逻辑上的 ByteBuf, 避免了传统通过内存拷贝的方式将几个小 Buffer 合并成一个大的 Buffer。 addComponents 方法将 header 与 body 合并为一个逻辑上的 ByteBuf, 这 两个 ByteBuf 在 CompositeByteBuf 内部都是单独存在的, CompositeByteBuf 只是逻辑上是一个整体。

通过 FileRegion 包装的 FileChannel.tranferTo 方法 实现文件传输, 可以直 接将文件缓冲区的数据发送到目标 Channel,避免了传统通过循环 write 方 式导致的内存拷贝问题。
通过 wrap 方法, 我们可以将 byte[] 数组、ByteBuf、ByteBuffer 等包装成 一个 NettyByteBuf 对象, 进而避免了拷贝操作。

Selector BUG:若 Selector 的轮询结果为空,也没有 wakeup 或新消息处 理,则发生空轮询,CPU 使用率 100%,

Netty 的解决办法:对 Selector 的 select 操作周期进行统计,每完成一次 空的 select 操作进行一次计数,若在某个周期内连续发生 N 次空轮询,则触 发了 epoll 死循环 bug。重建 Selector,判断是否是其他线程发起的重建请 求,若不是则将原 SocketChannel 从旧的 Selector 上去除注册,重新注册 到新的 Selector 上,并将原来的 Selector 关闭。

回复

我来回复
  • 暂无回复内容

免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部