mmap

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top

全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`

mmap 是一个用于在文件和内存之间建立一个映射关系的 POSIX-compliant 系统调用。它允许程序员将一个文件或者其他对象映射进内存,这样的话,文件的部分就可以被当作数组来访问,这通常比传统的 read 和 write 方法更加高效。

mmap 的基本概念

当你使用 mmap 时,操作系统会创建一个新的内存区域,并将文件的内容映射到这个区域。这样,应用程序就可以通过指针直接访问文件内容,而不是通过读写文件的系统调用。这种方法可以提高文件操作的效率,因为它减少了系统调用的次数,并且可以实现多个进程之间的共享内存。

mmap 的优势

  • 性能提升:减少了系统调用的开销,因为数据不需要在用户空间和内核空间之间复制。

  • 内存共享:允许多个进程共享同一块内存区域,这对于进程间通信非常有用。

  • 延迟加载:文件的内容可以在需要时才被加载到内存中,而不是一开始就全部加载。

  • 随机访问:可以像访问普通内存数组一样随机访问文件的任何部分。

mmap 的使用场景

  • 文件读写:当需要频繁读写大文件时,mmap 可以提供更好的性能。

  • 内存映射数据库:如 SQLite,它使用 mmap 来提高数据库操作的效率。

  • 进程间通信:通过映射同一个文件到不同进程的地址空间,可以实现进程间共享数据。

mmap 的基本用法(在 POSIX 系统中)

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);
  • addr:建议的映射起始地址,通常设置为 NULL,由系统决定。

  • length:映射区域的长度。

  • prot:期望的内存保护标志,如 PROT_READPROT_WRITE

  • flags:影响映射区域的行为,如 MAP_PRIVATEMAP_SHARED

  • fd:被映射文件的文件描述符。

  • offset:文件中的偏移量,从哪里开始映射。

注意事项

  • 使用 mmap 时,需要确保文件描述符 fd 指向的文件足够大,至少要和映射区域一样大。

  • 映射建立后,可以使用 munmap 函数来解除映射。

  • 对映射区域的修改(如果允许)可能不会立即写回文件,可以使用 msync 来同步更改。

示例代码

#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("Error opening file for reading");
        return -1;
    }

    struct stat sb;
    if (fstat(fd, &sb) == -1) {
        perror("Error getting the file size");
        return -1;
    }

    void *file_in_memory = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (file_in_memory == MAP_FAILED) {
        close(fd);
        perror("Error mmapping the file");
        return -1;
    }

    // Now the file's content is available at file_in_memory

    // Don't forget to free the mmapped memory
    if (munmap(file_in_memory, sb.st_size) == -1) {
        close(fd);
        perror("Error un-mmapping the file");
        return -1;
    }

    close(fd);
    return 0;
}

在 Java 中,mmap 功能可以通过 java.nio 包中的 MappedByteBuffer 类来实现。Java 的 NIO(New Input/Output)提供了一种将文件直接映射到内存的方法,这可以通过 FileChannel 类的 map 方法来实现。

最后更新于