即使内存是物理共享的,每个进程都有自己的虚拟内存映射,并且即使映射相同的区域也会“消耗”一个独立的寻址空间 - 您可以在 VSIZE 列中看到它。在任何情况下(即使在malloc() 之后),内核都会为每个进程保留一个独立的寻址空间,但不会立即在后备存储中分配等效的页面。
一旦您开始读取/写入分配的内存,虚拟页面就会被分配到相应的后备存储:驻留集相应地增加。
如果您只是阅读,这些页面是“干净的”,如果您向它们写入,这些页面是“脏的”,直到它们不同步。 (参见/proc/PID/smaps、/proc documentation、man pmap:此工具可让您区分共享内存和私有内存、脏页和干净页)
MAP_POPULATE 选项立即预分配所有页面。如果映射为MAP_PRIVATE,则允许页面保持脏,直到它们没有与msync() 显式同步。脏页缓存在 RAM 中,事实上,随着使用私有映射的页面越多,可用的系统内存就会减少。
另一方面,使用MAP_SHARED,您需要内核保持虚拟页面与后备存储。
但是对于映射文件,后备存储不是内存,而是文件 - 因为它是交换空间。所以你有一个奇怪的效果,映射文件被算作常驻集。
这可以通过观察/proc/PID/status的内容来验证:
VmRSS size of memory portions. It contains the three
following parts (VmRSS = RssAnon + RssFile + RssShmem)
RssAnon size of resident anonymous memory
RssFile size of resident file mappings
RssShmem size of resident shmem memory (includes SysV shm,
mapping of tmpfs and shared anonymous mappings)
VmRSS 是通常报告为 RSS 的内容。
在这种情况下,RSS 不计算物理内存,而是文件映射:请求MAP_SHARED 时,系统总内存大部分不受影响,因为大部分没有缓存页面(缓存,脏页将计入RssAnon) .它们必须尽快刷新到共享的后备存储(文件)。
正如您正确观察到的那样,即使是共享的,每个进程也会计算一次 RSS。您可以在 /proc/PID/smaps 中找到另一个计数器 PSS(比例集大小) - 也请参阅此答案:
What does pss mean in /proc/pid/smaps
进程的“比例集大小”(PSS) 是它在内存中的页数,其中每个页除以共享它的进程数。因此,如果一个进程拥有 1000 个页面,并且与其他进程共享 1000 个页面,则其 PSS 将为 1500
请注意:您只能使用tmpfs 使用MAP_SHARED|MAP_POPULATE 来共享内存 - 否则您将使用基于文件的共享。如果您正在寻找 IPC 共享内存,请查看shmget()。
测试
我已经用一个小程序验证了我的语句,它从具有不同标志的文件中映射了 2 GB,然后用memset() 写入了 1/3 的页面。
MAP_PRIVATE
ps -u 输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
xxxx 15767 0.5 4.1 2004216 666944 pts/1 S+ 12:54 0:00 ./mm 1
来自/proc/PID/smaps:
7f143e5ec000-7f14b870c000 rw-p 00000000 fd:00 201562609 /home/xxxx/test/mm.dat
Size: 2000000 kB
Rss: 666668 kB
Pss: 666668 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 666668 kB
Referenced: 666668 kB
Anonymous: 666668 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
来自/proc/PID/status:
VmRSS: 666944 kB
RssAnon: 666560 kB
RssFile: 384 kB
RssShmem: 0 kB
MAP_PRIVATE | MAP_POPULATE
ps -u 输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
xxxx 17045 31.0 12.3 2004216 2000412 pts/1 S+ 13:01 0:01 ./mm 2
来自/proc/PID/smaps:
7f14aa983000-7f1524aa3000 rw-p 00000000 fd:00 201562609 /home/xxxx/test/mm.dat
Size: 2000000 kB
Rss: 2000000 kB
Pss: 2000000 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 2000000 kB
Referenced: 2000000 kB
Anonymous: 2000000 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
来自/proc/PID/status:
VmRSS: 2000412 kB
RssAnon: 2000032 kB
RssFile: 380 kB
RssShmem: 0 kB
MAP_SHARED
ps -u 输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
xxxx 17670 18.0 4.1 2004216 666944 pts/1 S+ 13:06 0:00 ./mm 3
来自/proc/PID/smaps:
7f01db018000-7f0255138000 rw-s 00000000 fd:00 201562609 /home/xxxx/test/mm.dat
Size: 2000000 kB
Rss: 666668 kB
Pss: 666668 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 666668 kB
Private_Dirty: 0 kB
Referenced: 666668 kB
Anonymous: 0 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr sh mr mw me ms sd
来自/proc/PID/status:
VmRSS: 666944 kB
RssAnon: 96 kB
RssFile: 666848 kB
RssShmem: 0 kB
MAP_SHARED | MAP_POPULATE
ps -u 输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
xxxx 18259 16.1 12.3 2004216 2000480 pts/1 S+ 13:10 0:00 ./mm 4
来自/proc/PID/smaps:
7ff0d020b000-7ff14a32b000 rw-s 00000000 fd:00 201562609 /home/xxxx/test/mm.dat
Size: 2000000 kB
Rss: 2000000 kB
Pss: 2000000 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 2000000 kB
Private_Dirty: 0 kB
Referenced: 2000000 kB
Anonymous: 0 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr sh mr mw me ms sd
来自/proc/PID/status:
VmRSS: 2000480 kB
RssAnon: 96 kB
RssFile: 2000384 kB
RssShmem: 0 kB
MAP_SHARED | MAP_POPULATE,两个实例
ps -u 输出:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
xxxx 18259 0.1 12.3 2004216 2000480 pts/1 S 13:10 0:00 ./mm 4
xxxx 19521 5.8 12.3 2004216 2000480 pts/1 S+ 13:19 0:00 ./mm 4
来自/proc/PID/smaps,只有一个第一个 PID:
7ff0d020b000-7ff14a32b000 rw-s 00000000 fd:00 201562609 /home/xxxx/test/mm.dat
Size: 2000000 kB
Rss: 2000000 kB
Pss: 1000000 kB
Shared_Clean: 2000000 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 2000000 kB
Anonymous: 0 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr sh mr mw me ms sd
来自/proc/PID/status:
VmRSS: 2000480 kB
RssAnon: 96 kB
RssFile: 2000384 kB
RssShmem: 0 kB