龙空技术网

在零拷贝上吹了牛逼的Netty

程序猿猩球 190

前言:

当前同学们对“netty最好的视频”大体比较关切,各位老铁们都想要知道一些“netty最好的视频”的相关内容。那么小编在网摘上搜集了一些关于“netty最好的视频””的相关文章,希望大家能喜欢,我们一起来学习一下吧!

开篇

本文内容绝对值得一看!

不少关于Netty的文章和视频都表达一个意思,Netty之所以牛逼其中一个原因就是因为它的零拷贝机制。

那么这个零拷贝到底是什么?根据我查阅资料,发现Netty的零拷贝体现在下面3个核心技术点,我们一起来看看真相吧!

正文文件传输

可以和Netty零拷贝,扯上关系的第一个零拷贝就是Linux的零拷贝。我们用一个典型的文件传输案例来聊聊!

这个典型的案例中,经过了如下2步

文件通过内核空间到用户空间的读取然后又通过用户空间写到了内核空间

这样没有问题,但是我们如果让这个数据不通过用户空间,直接在内核态进行数据填充了,效果是不是更好,看下图?

上面这种数据不经过用户空间,直接在内核空间填充的技术,就是零拷贝。

Linux是提供了这类技术的,具体实现也有很多,这不是本文的重点,有兴趣的请自行谷歌。

Java的NIO提供了一个API叫做transferTo,而Netty也就在FileRegion中简单的包裹了一下,具体可以参考该类io.netty.channel.DefaultFileRegion#transferTo

综上:关于文件的零拷贝,这不是Netty原创的零拷贝,还是要归功于NIO的封装,当然最终还是要归功于系统!

内存拷贝

第二个Netty零拷贝相关的就是避C-Heap和Java-Heap的转换。

我们需要知道Java读取文件流或者网络流,其底层都是native的实现,就是说Java调用了C来实现的。

比如java.net.SocketInputStream#socketRead0

private native int socketRead0(FileDescriptor fd,                                   byte b[], int off, int len,                                   int timeout)        throws IOException;

比如java.io.FileInputStream#read0

private native int read0() throws IOException;

这种API调用方式,势必会导致C-Heap 到Java-Heap的一层拷贝,这个是会耗费资源的。

NIO本身就实现在堆外的内存DirectByteBuffer,Netty的ByteBuf也就是在这个上面封装了一层。我们来看看Netty如何应用NIO的DirectByteBuffer来避免这一层C-Java的拷贝的。

内存池的ByteBuf创建的调用链路

io.netty.buffer.PooledByteBufAllocator#newDirectBuffer  io.netty.buffer.UnsafeByteBufUtil#newUnsafeDirectByteBuf     io.netty.buffer.UnpooledDirectByteBuf#UnpooledDirectByteBuf  			io.netty.buffer.UnpooledDirectByteBuf#allocateDirect  				java.nio.DirectByteBuffer#DirectByteBuffer(int)

综上:关于ByteBuffer的零拷贝,不是Netty原创还是要归功于NIO

CompositeByteBuf

这个才算是Netty在零拷贝上的真实体现,原创精品,哈哈!

Composite是复合的意思,可以看出是复合ByteBuf,这是一个NIO的ByteBuffer的包装器。可以将实际上多个ByteBuf复合成逻辑上的一个ByteBuf

public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable < ByteBuf > {	private Component[] components; // resized when needed	private static final class Component {		final ByteBuf srcBuf; // the originally added buffer		final ByteBuf buf; // srcBuf unwrapped zero or more times		//这里:构造函数		Component(ByteBuf srcBuf, int srcOffset, ByteBuf buf, int bufOffset, int offset, int len, ByteBuf slice) {			//....		}	}}

关键信息如上

其内部是一个Component[],每一个Component又包含了ByteBuf构造函数中的offset很明显就是访问对应ByteBuf时候的偏移量了结语

Netty在零拷贝上的原创应该仅仅就是CompositeByteBuf了,其他2处顶多是包装了下NIO的特性。

但是你不能怀疑Netty仍然是java用的最广泛的网络通信框架,绝对值得广大Javaer学习

欢迎大家评论留言,一起讨论~

标签: #netty最好的视频