gpt4 book ai didi

java - 为什么 mmap()(内存映射文件)比 read() 快

转载 作者:IT王子 更新时间:2023-10-29 00:49:28 26 4
gpt4 key购买 nike

最近在研究Java NIO的MappedByteBuffer。我读过一些关于它的帖子,所有帖子都提到“mmap() 比 read() 快”

在我的结论中:

  1. 我对待 MappedByteBuffer == Memory Mapped File == mmap()

  2. read() 必须通过磁盘文件 -> 内核 -> 应用程序读取数据,因此它具有上下文切换和缓冲区复制

  3. 他们都说 mmap() 的复制或系统调用比 read() 少,但据我所知,它还需要在您第一次访问文件数据时从磁盘文件中读取。所以第一次读取:虚拟地址 -> 内存 -> 页面错误 -> 磁盘文件 -> 内核 -> 内存。除了你可以随机访问它,最后 3 个步骤(磁盘文件 -> 内核 -> 内存)与 read() 完全相同,那么 mmap() 怎么可能比 read() 更少复制或系统调用?

  4. mmap()和交换文件有什么关系,操作系统会把内存中最少使用的文件数据放入交换空间(LRU)吗?因此,当您第二次访问这些数据时,操作系统从交换而不是磁盘文件中检索它们(无需复制到内核缓冲区),这就是为什么 mmap() 具有较少的复制和系统调用?

  5. 在 java 中,MappedByteBuffer 是在堆外分配的(它是一个直接缓冲区)。那么,当您从 MappedByteBuffer 中读取时,是否意味着它需要从 java 堆之外再向 java 堆中复制一份额外的内存?

有人能回答我的问题吗?谢谢:)

最佳答案

1:是的,这本质上就是 MappedByteBuffer。

2:“磁盘文件->内核”不一定涉及拷贝。

3:使用内存映射文件,一旦内核将文件读入其缓存,它就可以简单地将缓存的那部分映射到您的进程中——而不必将数据从缓存复制到您的某个位置流程指定。

4:如果内核决定从内存映射文件中换出一个页面,它不会将该页面写入页面文件;它会在丢弃页面之前将页面写入原始文件(它映射的文件)。将其写入页面文件是不必要的,并且会浪费页面文件空间。

5:是的。例如,如果您调用 get(byte[]),那么数据将从堆外映射复制到您的数组中。请注意,get(byte[]) 等函数需要为任何 类型的缓冲区复制数据 - 这并不特定于内存映射文件。

关于java - 为什么 mmap()(内存映射文件)比 read() 快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29113714/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com