mmap vs read
先放个结论:
- 内存映射通常比随机访问更快,尤其访问的对象是分离的和不可预测的.
- 内存映射会持续占用pages, 直到完成访问. 这意味当长时间重度使用一个文件很久之前, 然后你关闭了它, 然后再重新打开, 它会直接cache hit, 文件命中. 而Read方法, 这个文件已经早被flush走了. mmap 用完立马丢弃它, 它把文件映射到了内存上.
- Read读文件比较简单, 而且比较快.
总结, 使用mmap: 访问数据随机地, 保存它长时间, 或想着共享给其它进程; Read 适合访问数据连续存储的数据, 或者读完就丢弃掉.
https://stackoverflow.com/questions/45972/mmap-vs-reading-blocks
上述的Stackoverflow上的讨论非常值得阅读,高票下的评论区在争论mmap的开销问题, 尤其是连续的文件读取的性能上.
一.操作数据的两种方式
https://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/
Usually in the UNIX world you have 2 ways of accessing/manipulating data: memory addresses or streams (files). Manipulating data via memory addresses means pointers, offsets, malloc/free, etc. Stream interfaces manipulate data via read/write/seek system calls for files and send/recv/etc for sockets.
通常在UNIX世界中,有两种访问/操作数据的方式:内存地址或流(文件)。文件的操作大多是基于流操作。
- 通过内存地址操作数据意味着指针,偏移,malloc / free等。
- 流接口操作数据通过对文件的系统调用( read/write/seek) 和socket操作(send / recv / etc)。
二.文件操作的两种方式
1. 标准文件I/O
I/O的原理: https://blog.csdn.net/jfengamarsoft/article/details/76216486
I/O请求包括数据从缓冲区排出(写操作)和数据填充缓冲区(读操作)。 每一次IO操作,都会发生用户态--内核态
这种 system call。
I/O操作有一个巨大的缺陷,就是当文件很大,比如有1亿行时,如果每读一行都进行一次IO操作,那么,这个系统调用的次数是1亿多次,频繁的IO操作严重影响程序的性能。
2. 内存映射I/O
内存映射意味着将文件加载到内存的用户空间,这意味着内存地址与文件中的字之间存在一对一的对应关系。此资源通常是物理存在于磁盘上的文件,但也可以是设备,共享内存对象或操作系统可通过文件描述符引用的其他资源。一旦存在,文件和存储空间之间的这种相关性允许应用程序将映射部分视为主存储器。程序员可以直接通过内存访问文件,与任何其他内存驻留数据相同 - 甚至可以允许写入内存区域透明地映射回磁盘上的文件。
优点: 如果一个大文件,假设每次进行内存映射50M,那么I/O操作的次数便少了, 提高了I / O性能。
缺点: 对于小文件,内存映射文件会导致浪费空间。因为内存映射始终与页面大小对齐,大多为4 KB。因此,5 KB文件将分配8 KB,因此浪费了3 KB。
3.两个方法的对比:
https://en.wikipedia.org/wiki/Memory-mapped_file
- 访问内存映射文件比使用直接读写操作更快。首先,系统调用比程序本地内存的简单更改慢几个数量级。其次,在大多数操作系统中,实际映射的内存区域是内核的页面缓存(文件缓存),这意味着不需要在用户空间中创建副本。
- 只有具有MMU的硬件架构才能支持内存映射文件。在没有MMU的体系结构中,操作系统可以在发出映射请求时将整个文件复制到内存中,但如果只访问文件的一小部分,这将非常浪费和缓慢,并且只能用于文件这将适合可用的内存。
简而言之,内存映射性能更好。由于系统调用开销和内存复制,标准I/O方法成本很高。内存映射文件的另一个常见用途是在多个进程之间共享内存。在现代保护模式操作系统中,通常不允许进程访问分配给另一进程使用的存储器空间,内存映射可以安全地共享内存。
三. python mmap = 内存映射I/O
https://www.safaribooksonline.com/library/view/linux-system-programming/0596009585/ch04s03.html
上面这篇文章很好讲述了mmap的原理: 即
As an alternative to standard file I/O, the kernel provides an interface that allows an application to map a file into memory, meaning that there is a one-to-one correspondence between a memory address and a word in the file. The programmer can then access the file directly through memory, identically to any other chunk of memory-resident data—it is even possible to allow writes to the memory region to transparently map back to the file on disk.
mmap本质上是内存映射。文件被映射到内存之后,这个文件就如同一个字符串变量一样,可以随意的操作,诸如 end/recv/
等socket操作。
作为标准文件I / O的替代,内核提供了一个允许应用程序将文件映射到内存的接口,这意味着内存地址与文件中的字之间存在一对一的对应关系。然后程序员可以直接通过内存访问文件,与任何其他内存驻留数据相同 - 甚至可以允许写入内存区域透明地映射回磁盘上的文件。
读取和写入内存映射文件可避免在使用read( )或write( )系统调用时发生的无关副本,其中必须将数据复制到用户空间缓冲区和从用户空间缓冲区复制数据。
四. 发生的Bug
在mmap
读取一个10G 大文件(系统镜像)时, 我犯了一些错误:
1.在使用mmap时,我想当然以为系统会自动的cache, 执行swamp in 和 swamp out。 实际上mmap如果不指定分页数和读取的字节,它会直接读取整个文件。导致随着find的操作不断执行,内存越来越小...这里有个好处是“延迟加载”,因此即使对于非常大的文件也使用少量RAM。 所以当我的的虚拟内存资源变得饱和时,会发生trash(颠簸),从而导致分页状态不变,排除了大多数应用程序级别的处理。这会导致计算机性能下降或崩溃。这种情况可以无限期地持续下去,直到用户关闭某些正在运行的应用程序或活动进程释放额外的虚拟内存资源。
https://stackoverflow.com/questions/31963124/memory-leakish-when-using-re-and-mmap
后来指定读取的offset,解决了这个问题。
offset = 0
length = mmap.ALLOCATIONGRANULARITY * 10
with open(p, "rb") as f:
while offset < file_size:
mm = mmap.mmap(f.fileno(), length=length, offset=offset,
access=mmap.ACCESS_READ)
offset += (mmap.ALLOCATIONGRANULARITY * 10)
2.在使用mmap时,由于mmap中使用了find()操作,它其实是socket操作,在不停地执行该操作时,导致WebSocket被阻塞,不能与前端进行交互。 由于这个原因,我最终还是放弃了mmap。
3.标准文件I/O的read()操作也可以指定字节读取,这是我想当然以为它一次读完了。
mmap vs read的更多相关文章
- Python之mmap内存映射模块(大文本处理)说明
背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过 ...
- MMAP和DIRECT IO区别
看完此文,题目不言自明.转自 http://blog.chinaunix.net/uid-27105712-id-3270102.html 在Linux 开发中,有几个关系到性能的东西,技术人员非常关 ...
- mmap为什么比read/write快(兼论buffercache和pagecache)
参考文献: <从内核文件系统看文件读写过程>http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool& ...
- 认真分析mmap:是什么 为什么 怎么用
mmap基础概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.实现这样的映射关系后,进程就可以采用指 ...
- Linux下TomcatVM参数修改:Native memory allocation (mmap) failed to map 3221225472 bytes for committing reserved memory.
不可行的方法最初我直接修改catalina.sh, 将JAVA_OPTS变量加上了 -server -Xms1G -Xmx1G -XX:+UserG1GC最初看起来没啥问题,但是当服务器运行几天后,发 ...
- Python多进程(2)——mmap模块与mmap对象
本文介绍Python mmap模块与mmap对象的用法. mmap 模块提供“内存映射的文件对象”,mmap 对象可以用在使用 plain string 的地方,mmap 对象和 plain stri ...
- epoll里面mmap释疑
今天看到有文章说epoll里面用了mmap,还说进程不需要从内核读数据,只需要从用户态buffer读数据就可以.觉得很神奇,就查了一下,发现完全不是描述的那样.实际上,只是把要传递的fd通过mmap来 ...
- mmap和shm共享内存的区别和联系
共享内存的创建 根据理论: 1. 共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制.共享内存可以通过mmap()映射普通文件(特殊情况下还可以采用匿 ...
- MMAP和DIRECT IO区别【转】
转自:http://www.cnblogs.com/zhaoyl/p/5901680.html 看完此文,题目不言自明.转自 http://blog.chinaunix.net/uid-2710571 ...
- 认真分析mmap:是什么 为什么 怎么用【转】
转自:http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool&utm_medium=referral 阅读目录 ...
随机推荐
- PHP将图片转base64格式函数
base64的好处是什么?今天在跟小伙伴讨论这个问题,要是全站用Php把图片转为base64行不行? 1. 提升性能: 网页上的每一个图片,都是需要消耗一个 http 请求下载而来的, 图片的下载始终 ...
- 《MySQL性能优化篇》阅读笔记
建表的时候,不要用null赋默认值,如:字符串的设置'',数据类型的设为0,不要将null设为默认值. 在MySQL中没有 full [outer] join,用union代替 各种 JOIN SQL ...
- centos7删除Apache组件
非特殊需要不要删除centos7中Apache等组件!首先查看centos中Apache版本(前面我们说了centos7删除PHP,centos7删除MariaDB,可能很多朋友会有疑问为什么要把所有 ...
- 重新学习Spring注解——AOP
面向切面编程——思想:在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处运用,而无须修改受影响的类. 切面:横切关注点可以被模块化为特殊的类. 优点: 1.每个关注点都集中在 ...
- Docker Hello-World镜像运行测试
一.命令:docker run hello-world 命令解释:以docker客户端命令的方式运行hello-world镜像 命令运行结果: hadoop@Docker:/opt/docker$ d ...
- POJ2536-Gopher II-(匈牙利算法)
题意:n只老鼠,m个洞,s秒逃命,逃命速度为v,一个洞只能保住一只老鼠,最少多少只老鼠会被老鹰抓到. 题解:找出每只老鼠有哪些洞可以保命,建立二分图,算出最大匹配,不是求保住命的老鼠,而是求被抓住的老 ...
- GrowingIO配置
一.什么是UTM参数UTM是一套标准的跟踪渠道流量的参数,你可以通过它来跟踪访问你网站的流量来自于哪些渠道.哪些媒介等. 二.高级用法 UTM参数包括了utm_source在内的5个参数,分别是: 参 ...
- Anaconda3(4)安装pytorch
安装链接 https://pytorch.org/ 0在anaconda3安装python3.6环境 https://blog.csdn.net/u012005313/article/details ...
- TypeScript 解构和展开
解构数组 解构数组元素 let input = [1, 2]; let [first, second] = input; console.log(first,second); 交换值 [first, ...
- 《深度学习框架PyTorch:入门与实践》读书笔记
https://github.com/chenyuntc/pytorch-book Chapter2 :PyTorch快速入门 + Chapter3: Tensor和Autograd + Chapte ...