零拷贝技术和多路复用技术是现代计算机系统和网络编程中两项重要的优化手段,旨在提高数据处理和传输的效率。如高性能框架 Netty 中,即使用了零拷贝技术又使用了多路复用技术,同时来保证 Netty 框架的高性能运行。
零拷贝(Zero-copy)技术是一种计算机操作系统中用于提高数据传输效率的优化策略。在传统的数据传输过程中,需要将数据从一个缓冲区拷贝到另一个缓冲区,然后再传输给目标。这涉及到多次的 CPU 和内存之间的数据拷贝操作,会消耗 CPU 的时间和内存带宽。而零拷贝技术通过直接共享数据的内存地址,避免了中间的拷贝过程,从而提高了数据传输的效率。
要搞明白零拷贝技术就要先搞清楚传统 IO 的执行流程,传统的 IO 的执行流程如下:
操作系统有用户态和内核态之分,这是因为计算机体系结构中的操作系统设计了两个不同的执行环境,以提供不同的功能和特权级别。
DMA(Direct Memory Access,直接内存访问)技术,绕过 CPU,直接在内存和外设之间进行数据传输。这样可以减少 CPU 的参与,提高数据传输的效率。
零拷贝技术可以利用 Linux 下的 MMap、sendFile 等手段来实现,使得数据能够直接从磁盘映射到内核缓冲区,然后通过 DMA 传输到网卡缓存,整个过程中 CPU 只负责管理和调度,而无需执行实际的数据复制指令。
MMap(Memory Map)是 Linux 操作系统中提供的一种将文件映射到进程地址空间的一种机制,通过 MMap 进程可以像访问内存一样访问文件,而无需显式的复制操作。
使用 MMap 可以把 IO 执行流程优化成以下执行步骤:
传统的 IO 需要四次拷贝和四次上下文(用户态和内核态)切换,而 MMap 只需要三次拷贝和四次上下文切换,从而能够提升程序整体的执行效率,并且节省了程序的内存空间。
在 Linux 操作系统中 sendFile() 是一个系统调用函数,用于高效地将文件数据从内核空间直接传输到网络套接字(Socket)上,从而实现零拷贝技术。这个函数的主要目的是减少 CPU 上下文切换以及内存复制操作,提高文件传输性能。
使用 sendFile() 可以把 IO 执行流程优化成以下执行步骤:
在 Java 中,以下几个地方使用了零拷贝技术:
多路复用技术则是一种让单个进程(或线程)能够同时监视多个描述符(如文件描述符、socket描述符)的技术,当其中任何一个描述符准备好进行读、写或者异常操作时,就会通知该进程。这种方式可以显著提高并发处理能力,减少系统开销,特别是在处理大量并发连接时。
主要的多路复用技术包括:
在 Java 中,可以通过 NIO(非阻塞 I/O)库中的 Selector 实现多路复用,结合诸如 FileChannel.transferTo() 等方法实现零拷贝,从而在开发高性能网络应用和服务时显著提升数据处理和传输的效率。
Netty 中使用了哪种零拷贝技术?它的多路复用和 NIO 的多路复用有什么区别?
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。