在Linux中观察共享的映射文件内存

时间:2018-12-06 14:26:00

标签: c linux system-calls shared-memory mmap

我正在使用mmap syscall加载文件内存以供其他几个进程读取(带有标志MAP_SHAREDMAP_POPULATE可以提前加载所有内存。)

检查进程内存消耗似乎忽略了共享映射文件内存的事实。根据{{​​1}}命令,每个进程的内存使用情况都包含内存中的整个映射文件。

有没有办法区分共享和私有进程内存?

1 个答案:

答案 0 :(得分:2)

即使内存是物理共享的,每个进程也都有其自己的虚拟内存映射,即使映射相同的区域也将“消耗”一个独立的寻址空间-您可以在VSIZE列中看到它。在任何情况下(甚至在malloc()之后),内核都会为每个进程保留一个独立的寻址空间,但不会立即在后备存储区中分配等效页。

一旦您开始对分配的内存进行读/写,虚拟页面就会被分配给相应的后备存储区:驻留集会相应增加。

如果您刚刚阅读这些页面,它们将是“干净的”,如果您对其进行写入,则它们将是“脏的”,直到它们不同步为止。 (请参见/proc/PID/smaps/proc documentationman 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时,系统总内存几乎不受影响,因为几乎没有页面被缓存(缓存的脏页面将计入{{ 1}})。必须尽快将它们刷新到共享的后备存储区(文件)。

正如您正确观察到的那样,即使共享RSS,每个进程也会对RSS进行一次计数。您可以在RssAnon中找到另一个计数器PSS(比例设置大小)-也请参见此答案:

What does pss mean in /proc/pid/smaps

  

一个进程的“比例集大小”(PSS)是它在内存中具有的页面数,其中每个页面除以共享它的进程数。因此,如果一个进程本身拥有1000页,并且与另一个进程共享1000页,则其PSS将为1500

一个注意事项:您只能使用/proc/PID/smaps来使用MAP_SHARED|MAP_POPULATE来共享内存-否则,您将使用基于文件的共享。如果您正在寻找IPC共享内存,请查看tmpfs

测试

我已经用一个微型程序验证了我的语句,该程序从具有不同标志的文件映射了2 GB,然后使用shmget()写入了1/3页。

MAP_PRIVATE

memset()输出:

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

MAP_PRIVATE | MAP_POPULATE

VmRSS: 666944 kB RssAnon: 666560 kB RssFile: 384 kB RssShmem: 0 kB 输出:

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

MAP_SHARED

VmRSS: 2000412 kB RssAnon: 2000032 kB RssFile: 380 kB RssShmem: 0 kB 输出:

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

MAP_SHARED | MAP_POPULATE

VmRSS: 666944 kB RssAnon: 96 kB RssFile: 666848 kB RssShmem: 0 kB 输出:

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

MAP_SHARED | MAP_POPULATE,两个实例

VmRSS: 2000480 kB RssAnon: 96 kB RssFile: 2000384 kB RssShmem: 0 kB 输出:

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 ,仅第一个PID:

/proc/PID/smaps

来自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