Java NIO 核心知识.下

[NIO 零拷贝](#NIO 零拷贝)

零拷贝是提升 IO 操作性能的一个常用手段,像 ActiveMQ、Kafka 、RocketMQ、QMQ、Netty 等顶级开源项目都用到了零拷贝。

零拷贝是指计算机执行 IO 操作时,CPU 不需要将数据从一个存储区域复制到另一个存储区域,从而可以减少上下文切换以及 CPU 的拷贝时间。也就是说,零拷贝主要解决操作系统在处理 I/O 操作时频繁复制数据的问题。零拷贝的常见实现技术有: mmap+writesendfilesendfile + DMA gather copy

下图展示了各种零拷贝技术的对比图:

可以看出,无论是传统的 I/O 方式,还是引入了零拷贝之后,2 次 DMA(Direct Memory Access) 拷贝是都少不了的。因为两次 DMA 都是依赖硬件完成的。零拷贝主要是减少了 CPU 拷贝及上下文的切换。

Java 对零拷贝的支持:

  • MappedByteBuffer 是 NIO 基于内存映射(mmap)这种零拷⻉⽅式的提供的⼀种实现,底层实际是调用了 Linux 内核的 mmap 系统调用。它可以将一个文件或者文件的一部分映射到内存中,形成一个虚拟内存文件,这样就可以直接操作内存中的数据,而不需要通过系统调用来读写文件。
  • FileChanneltransferTo()/transferFrom()是 NIO 基于发送文件(sendfile)这种零拷贝方式的提供的一种实现,底层实际是调用了 Linux 内核的 sendfile系统调用。它可以直接将文件数据从磁盘发送到网络,而不需要经过用户空间的缓冲区。关于FileChannel的用法可以看看这篇文章:Java NIO 文件通道 FileChannel 用法

代码示例:

private void loadFileIntoMemory(File xmlFile) throws IOException {

FileInputStream fis = new FileInputStream(xmlFile);

// 创建 FileChannel 对象

FileChannel fc = fis.getChannel();

// FileChannel.map() 将文件映射到直接内存并返回 MappedByteBuffer 对象

MappedByteBuffer mmb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

xmlFileBuffer = new byte[(int)fc.size()];

mmb.get(xmlFileBuffer);

fis.close();

}

总结

这篇文章我们主要介绍了 NIO 的核心知识点,包括 NIO 的核心组件和零拷贝。

如果我们需要使用 NIO 构建网络程序的话,不建议直接使用原生 NIO,编程复杂且功能性太弱,推荐使用一些成熟的基于 NIO 的网络编程框架比如 Netty。Netty 在 NIO 的基础上进行了一些优化和扩展比如支持多种协议、支持 SSL/TLS 等等。

相关推荐
神仙别闹7 分钟前
基于 Java 语言双代号网络图自动绘制系统
java·开发语言
猫爪笔记15 分钟前
JAVA基础:单元测试;注解;枚举;网络编程 (学习笔记)
java·开发语言·单元测试
aqua353574235819 分钟前
杨辉三角——c语言
java·c语言·数据结构·算法·蓝桥杯
API快乐传递者20 分钟前
用 Python 爬取淘宝商品价格信息时需要注意什么?
java·开发语言·爬虫·python·json
yang_shengy30 分钟前
【JavaEE】认识进程
java·开发语言·java-ee·进程
阿乾之铭32 分钟前
Spring boot框架下的Java 反射
java·spring boot·后端
麻衣带我去上学1 小时前
Spring源码学习(五):Spring AOP
java·学习·spring
北欧人写代码2 小时前
idea java 项目右键new file时 为什么是 kotlin class 不是普通class
java·kotlin·intellij-idea
笔墨登场说说2 小时前
JDK 里面的线程池和Tomcat线程池的区别
java·servlet·tomcat
on the way 1232 小时前
java.io.IOException: Too many open files
java·开发语言