怎么样申请网站域名,百度指数是搜索量吗,如何把自己做的网站 放在网上,仿站在线Netty ByteBuf工作原理#xff0c;和NIO里ByteBuffer区别#xff1f; Java NIO 提供了ByteBuffer 作为它 的字节容器#xff0c;但是这个类使⽤起来过于复杂#xff0c;⽽且也有些繁琐。
ByteBuf是Netty框架中的一个关键类#xff0c;专门设计来处理字节数据#xff0c;… Netty ByteBuf工作原理和NIO里ByteBuffer区别 Java NIO 提供了ByteBuffer 作为它 的字节容器但是这个类使⽤起来过于复杂⽽且也有些繁琐。
ByteBuf是Netty框架中的一个关键类专门设计来处理字节数据旨在替代Java标准NIO库中的ByteBuffer。
相较于ByteBufferByteBuf引入了更高效的数据操作方式和更丰富的API支持。其核心优势在于支持自动读写切换、内存池化以及零拷贝技术这些特性共同作用使得ByteBuf在数据处理方面的性能大大超越了传统的ByteBuffer。
一、自动读写切换
1.NIO 里的 ByteBuffer 对于 Java NIO 的 Buffer其有几个重要的属性positionlimitcapacity其中position代表的是下一个读或写的位置limit是可被读或写的最高位而capacity就是 Buffer 的容量了之所以要在读和写切换的时候进行手动操作clear()flip()主要是因为在 NIO 中position和limit在读的时候代表的是下一个需读的位和可读的最高位但是在写的时候又代表下一个需写的位和可写的最高位其实就是capacity换句话说这两个变量在不同的操作场景下有不同的含义对应值也不同所以需要在读写切换的时候进行手动操作。
2.Netty里的ByteBuf
而 Netty 的 ByteBuf 则对这一点做了改进其针对读写操作分别增加上了readerIndex原来的positionwriterIndex对应 NIO 中的 limit使用的时候不需要考虑读写转换。
读的时候就变动readerIndex的值此时可读的最高位其实就是writerIndex写的时候就变动writerIndex的值此时可写的最高位就是capacity
说白了就是两个变量分别管理读和写的操作位互不冲突也就不存在读写切换的时候手动操作。 二、内存池化
1.给 ByteBuf 分配内存
在 Netty 中ByteBuf 用来作为数据的容器是一种会被频繁创建和销毁的对象。 分配 ByteBuf 需要的内存空间有三种方式 堆缓冲区HeapByteBuf 优点内存的分配和回收速度⽐较快可以被JVM⾃动回收。由于在堆上被 JVM 管理在不被使⽤时可以快速释放。可以通过ByteBuf.array() 来获取 byte[] 数据。 缺点如果进⾏socket的IO读写需要额外做⼀次内存复制将堆内存对应的缓冲区复制到内核Channel中性能会有⼀定程度的下降。 直接缓冲区DirectByteBuf堆外内存。 优点将它写⼊或从Socket Channel中读取时由于减少了⼀次内存拷⻉速度⽐堆内存块。 缺点相⽐堆内存它的分配和回收速度会慢⼀些。 复合缓冲区CompsiteByteBuf顾名思义就是将上述两类缓冲区聚合在⼀起。Netty 可以将堆缓冲区和直接缓冲区的数据放在⼀起让使⽤更加⽅便。 但抛开哪个代价高哪个代价低不说光是频繁创建和频繁销毁这一点就已奠定了效率不高的基调。Netty 为了解决这个问题引入了池化技术池化技术的思想不复杂和线程池思想类似说白了就是对一些可重用的对象用完不回收后面需要再次使用以减少创建和销毁对象带来的资源损耗。
2.引用计数 来管理 ByteBuf
引用计数就是实现池化的关键技术点
不过并非只有池化的 ByteBuf 才有引用计数非池化的也会有引用。
ByteBuf实现了ReferenceCounted接口表明该类是一个引用计数管理对象。 每一个引用计数对象都维护了一个自身的引用计数通过refCnt()方法可以得到当前的引用计数。当第一次被创建时引用计数为 1调用retain()方法会增加自身的引用计数值。调用release()方法减少当前的引用计数值如果引用计数值为 0当前的 ByteBuf 自动释放返回值为true。 引用计数机制有效预防内存泄漏确保及时回收不再使用的内存资源。
3.Netty 实现内存池化
Netty 提供了两种 ByteBufAllocator 的实现分别是
PooledByteBufAllocator实现了 ByteBuf 的对象的池化提⾼性能减少并最⼤限度地减少内存碎⽚。UnpooledByteBufAllocator没有实现对象的池化每次会⽣成新的对象实例。 如何释放 手动释放调用release()方法自动释放略 释放后如何 池化的 ByteBuf那么就会重新进池子以待重用非池化的 ByteBuf则销毁底层的字节数组引用或者释放对应的堆外内存。 池化技术通过重用已有的ByteBuf实例减少了频繁的内存分配与回收操作显著提升了性能。 三、零拷贝技术
Netty必知必会一——零拷贝-CSDN博客
slice()创建一个与原始ByteBuf共享数据的新视图但拥有独立的读写索引。duplicate()创建一个完整的ByteBuf副本共享数据内容但维护一套独立的索引。compositeByteBuf()可以将多个ByteBuf合并为一个逻辑上的ByteBuf实现数据的逻辑组合而非物理合并。 四、参考
一文读懂网络框架Netty_文化 方法_蔡昱星_InfoQ精选文章 Netty详解ByteBuf_netty bytebuf-CSDN博客 Netty之ByteBuf详解与实战-CSDN博客