我的 RHEL7 上的输出lsof
显示,一个带有文件描述符的文件mem
被 40 个进程使用。这是否意味着这个文件在内存中映射了 40 次还是什么?有人可以解释一下内存映射文件的含义吗?这是否意味着我的记忆中有40次了?
# lsof /usr/lib/locale/locale-archive 命令 PID 用户 FD 类型 设备大小/关闭 节点名称 vmtoolsd 605 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive Agetty 656 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive 调整 963 root mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive iostat 1199 adm mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive chkMtaMem 1205 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive snmpd 4704 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive 睡眠 5461 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive cmsubagt 6487 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive 睡眠 6649 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc1 6803 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc2 6835 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc3 6836 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc4 6856 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc5 6884 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc6 6889 usr 内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc7 6893 usr1 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive cmfpagt 7704 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc8 7943 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive crond 8001 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive sh 8005 adm mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive iostat 8014 adm mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive crond 20427 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc9 20648 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc10 20649 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc10 20760 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc9 20777 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc11 21353 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc12 21354 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc13 21355 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc14 21356 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc15 21357 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc16 21358 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc17 21554 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc18 21569 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc19 21590 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc20 21647 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc21 22016 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc22 22017 根内存 REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc23 22104 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive proc24 22122 usr2 mem REG 8,5 106070960 50808629 /usr/lib/locale/locale-archive
答案1
看看虚拟内存和物理内存之间的区别。
许多进程可以映射相同的物理内存。如果 10 个进程映射同一个文件,则 RAM 中最多会缓存一份副本。
如果内存不是共享的,那么如果一个进程更改了它,则在提交写入之前会复制这一页(包含更改)。 (因此并非所有内存都被复制。这称为写入时复制或 COW)。
内存映射文件是指您要求操作系统将文件映射到内存中。在您开始读/写之前,它不会加载文件,然后仅加载需要的内容。内存映射只是读/写/查找等的不同接口。您还可以通过读/写/查找来访问内存。
那么这是如何做到的呢?
这是通过认识到有些事情是相同的来完成的:即交换和文件是相同的;内存和文件缓存是相同的。因此,当您打开一个文件时,它会被映射为交换(不用担心它不会用于交换其他内容)。当您开始读取时,会生成段错误,并且操作系统将其从文件中交换(异常(段错误)由操作系统处理,因此不会传递给进程)(实际上它不是分段错误,这是一个页面错误)。使用内存或文件的接口并不重要。它们只是具有相同功能的接口。
答案2
是的,按照以下手册lsof
:
FD is the File Descriptor number of the file or:
cwd current working directory;
Lnn library references (AIX);
err FD information error (see NAME column);
jld jail directory (FreeBSD);
ltx shared library text (code and data);
Mxx hex memory-mapped type number xx.
m86 DOS Merge mapped file;
mem memory-mapped file;
mmap memory-mapped device;
pd parent directory;
rtd root directory;
tr kernel trace file (OpenBSD);
txt program text (code and data);
v86 VP/ix mapped file;
仅当它以非共享模式映射并且任何进程写入虚拟内存时,才需要物理内存中的多个文件副本。否则,如果没有发生写入(我不认为),则在任何进程读取内存之前,数据甚至不必占用物理内存。