当前位置: 首页 > 图灵资讯 > java面试题> javaNetty面试题-零拷贝技术

javaNetty面试题-零拷贝技术

来源:图灵教育
时间:2024-05-23 13:18:50
1.当用户进程发起 read() 调用后,上下文从用户态切换至内核态。DMA 引擎从文件中读取数据,并存储到内核态缓冲区,这里是第一次数据拷贝。

2.请求的数据从内核态缓冲区拷贝到用户态缓冲区,然后返回给用户进程。第二次数据拷贝的过程同时,会导致上下文从内核态再次切换到用户态。

3.用户进程调用 send() 方法期望将数据发送到网络中,用户态会再次切换到内核态,第三次数据拷贝请求的数据从用户态缓冲区被拷贝到 Socket 缓冲区。

4.最终 send() 系统调用结束返回给用户进程,发生了第四次上下文切换。第四次拷贝会异步执行,从 Socket 缓冲区拷贝到协议引擎中。

在 Linux 中系统调用 sendfile() 可以实现将数据从一个文件描述符传输到另一个文件描述符,从而实现了零拷贝技术。

在 Java 中也使用了零拷贝技术,它就是 NIO FileChannel 类中的 transferTo() 方法,它可以将数据从 FileChannel 直接传输到另外一个 Channel。

Netty 中的零拷贝技术除了操作系统级别的功能封装,更多的是面向用户态的数据操作优化,主要体现在以下 5 个方面:

●堆外内存,避免 JVM 堆内存到堆外内存的数据拷贝。

●CompositeByteBuf 类,可以组合多个 Buffer 对象合并成一个逻辑上的对象,避免通过传统内存拷贝的方式将几个 Buffer 合并成一个大的 Buffer。

●通过 Unpooled.wrappedBuffer 可以将 byte 数组包装成 ByteBuf 对象,包装过程中不会产生内存拷贝。

●ByteBuf.slice ,slice 操作可以将一个 ByteBuf 对象切分成多个 ByteBuf 对象,切分过程中不会产生内存拷贝,底层共享一个 byte 数组的存储空间。

●Netty 使用 封装了transferTo() 方法 FileRegion,可以将文件缓冲区的数据直接传输到目标 Channel,避免内核缓冲区和用户态缓冲区之间的数据拷贝。