Ale*_*xis 7 c java linux io operating-system
我最近正在研究Java NIO的MappedByteBuffer.我已经阅读了一些关于它的帖子,所有人都提到"mmap()比read()更快"
在我的结论中:
我对待MappedByteBuffer == Memory Mapped File == mmap()
read()必须通过以下方式读取数据:磁盘文件 - >内核 - >应用程序,因此它具有上下文切换和缓冲区复制
他们都说mmap()比read()具有更少的复制或系统调用,但据我所知,它还需要在您第一次访问文件数据时从磁盘文件中读取.所以第一次读它:虚拟地址 - >内存 - >页面错误 - >磁盘文件 - >内核 - >内存.除了你可以随机访问它,最后3个步骤(磁盘文件 - >内核 - >内存)与read()完全相同,那么mmap()如何比read()更少复制或系统调用?
mmap()和交换文件之间的关系是什么,os是否会将最少使用的内存文件数据放入交换(LRU)?因此,当您第二次访问这些数据时,操作系统会从交换但不是磁盘文件中检索它们(不需要复制到内核缓冲区),这就是为什么mmap()具有较少的复制和系统调用?
在java中,MappedByteBuffer是从堆中分配的(它是一个直接缓冲区).所以当你从MappedByteBuffer中读取时,是否意味着它需要从Java堆外部再添加一个额外的内存副本到java堆中?
谁能回答我的问题?谢谢 :)
1:是的,这基本上就是MappedByteBuffer.
2:"磁盘文件 - >内核"不一定涉及复制.
3:使用内存映射文件,一旦内核将文件读入其缓存,它就可以简单地将缓存的那部分映射到您的进程中 - 而不必将数据从缓存复制到您的进程指定的位置.
4:如果内核决定从内存映射文件中换出页面,它将不会将页面写入页面文件; 在丢弃页面之前,它会将页面写入原始文件(从中映射的文件).将其写入页面文件将是不必要的并浪费页面文件空间.
5:是的.例如,如果您调用,get(byte[])则数据将从堆外映射复制到您的阵列中.请注意,诸如get(byte[])需要为任何类型的缓冲区复制数据之类的功能 - 这不是特定于内存映射文件的.