Memory-mapped file

2021-08-22补充:

错误的,但便于理解的结论:将 磁盘上的文件内容 映射到 内存条上

  • 好处:快速
    • 更改内存比磁盘快多了
  • 坏处:缺页调度耗时、内存浪费。
    • 缺页调度耗时(下文说了,就是实际内存条,没有这个映射的数据。需要申请将文件,加载到内存),缺页调度耗时 与 其他IO系统调用(write、read的API),你要权衡下,
    • 内存浪费:内存读取最小单位是page,假设page是4KB,映射个5KB文件到内存,最小分配两个page,8KB,浪费了3KB        

正确的是:

将虚拟内存 与 文件映射起来,使其一一对应。

虚拟内存:不是内存条,是虚拟内存

  • 让应用以为 它在用一根物理内存(内存条)。实际 系统内核(OS)帮你一通操作,APP实际操作的虚拟内存。
    •  应用操作  虚拟内存----》内核 各种映射---》物理内存
  •  N个进程用内存,你写程序,都以为自己独占了 内存条

File文件: 不是磁盘文件,而是各种 存储设备

  • Linux中 Everything is file
  • 无论是 socket、键盘、文本、屏幕、鼠标,说白了都是 内存块,进行读写操作。比如屏幕,就是存储了RGB数据的内存;键盘就是所有按键的内存,配上正在触发的按键;文本有 ASCII、UniCode 编码的数据。 再本质点,数据用二进制标志,都是存着0或1的存储单元。
  • 控制读写操作的程序,叫驱动。所以 外设(外围设备)键盘、鼠标,都需要装个驱动程序到让系统内核(类比JDK吧)
  • 所有的File,都通过FileDescriptor 指向(你理解为File的指针就行,错误的理解为路径也行,反正有了 FileDescriptor就可以操作File了)。具体看我的文章  FileDescriptor(文件描述符 )与Linux文件系统

-----------------2021-08-22 分割线---------

memory-mapping

直接将文件映射(一一对应)到内存中,通过file descriptor(文件描述符)引用。

Android应用:

    通过系统回调open打开Binder设备,然后将Binder mmap 到 内核和用户进程空间(IPC只需复制一次,Socket等一般需要两次)

优点是:

a.提高文件的的I/O性能,特别是针对大文件。小文件会导致浪费内存,因为映射的内存要跟page大小对齐(aglin page size)。大多数page size是4KiB。因此5KiB的文件就会分配8KiB,浪费3KiB。

b.memory map file比直接进行 读写操作(read and write  operation)快的原因:

   1.system call(系统调用)比 改变程序本地内存(local memory)慢几个数量级(system call是系统内核暴露的API,API内还会有多次的调用。但内存 则直接作用于 内存单元。)

    2.在多数操作系统中内存映射区域 实际在 内核的page cache(file cache)中,意味着不需要copy 到user space(用户空间)。(也就是两个应用访问同一个文件,第二次就不用读取到内存了)

c.对于application级别的memory-mapping操作 性能也好于 操作物理文件。应用可以直接读取更新文件,而不用从开头寻找 或者 重写整个文件到一个临时区域。因为memory-mapped file是在pages内部处理的。

d.一个潜在的好处是 lazy loading,对于大文件只需要较小的RAM,只需要加载需要编辑的数据到page中。但加载文件的整个内容,且文件size远大于可用内存时,会导致大量的paging发生,因为系统从disk读到memory的同时 还用从memory 写入 disk。

e.memory mapping被 virtual memory manager管理(也负责管理page file manager(页面调度)),memory mapped file一次加载 一整页(one entire page)到内存。page file manager从virtual memory system最重要的模块,所以加载page大小的块到内存 是系统高度优化的功能。(就是说memory-mapping是系统层面的功能,很多快的)

缺点是:

a.文件大于可用内存时,会使读取变得复杂。例如 32位架构系统 仅可直接寻址 4G或更小的文件。对于单个程序可用空间 甚至更少,一般在2~3G之间,具体由操作系统决定。

b.文件的I/O错误将报告进程  SIGSEGV/SIGBUS信号(在POSIX系统),EXECUTE_IN_PAGE_ERROR(在windows系统),如(可移动驱动被弹出,写时disk满了),这些情况都需要处理。

c.硬件架构需要支持Memory Management Unit,如果不支持 将把整个文件copy到内存,导致浪费内存、非常耗时,并且可用内存必须大于文件size。

d.因没有映射到进程的虚拟内存空间,有些情况下会比标准file I/O慢

应用:

1.最常用于process loader(进程加载器)(包括Windows、Unix-like系统),在进程开启时,系统使用memory mapped file将可执行文件、可加载模块 读入内存去执行。大部分memory-mapping sytem使用demand paging技术,即只在 页面被实际引用时 才将 文件加载到物理内存中。

2.多进程共享内存,多个进程同步映射 一个物理文件 到内存,并读取这个内存。例如windows系统通过memory-map 共享系统page文件的一段,以此共享数据。

类型:

Persisted(持久化的)

persisted file关联一个硬盘上的source file。在操作完成后 写入到disk中,适用于大的source file文件。

Non-persisted

不关联disk上的file。操作完成后数据丢失。适用于为IPC(进程间通信)创建共享内存。

平台支持:

POSIX系统(如 UNIX、Linux、MAC OS、OpenVMS)

    mmap() 方法

Windows

   CreateFileMapping()方法

Java语言

   FileChannel

Ruby

   Mmap

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值