在strace
我看来,几乎每个进程都打开并映射到内存ld.so.cache
。libc.so.6
至少我尝试过的那些过程是这样。这不是意味着这些进程被映射到进程内存很多很多很多次吗?
当然,这些文件非常小,但这不是有点浪费内存吗?
strace 输出显示这些正在使用MAP_PRIVATE
set 进行 mmap,这使得它具有写时复制功能,但每个进程似乎仍有一个新的映射。
我的问题:
- 我是否正确理解了正在发生的事情?也就是说,是否真的有这些文件的新副本映射到每个需要它们的进程的内存中(似乎是每个进程)?
- 是否存在某种类型的内存共享?也就是说,由于映射是写时复制的,因此许多进程是否正在查看相同的物理内存位置?
答案1
是的,每个进程都有自己所需的库的映射。
是的,大多数数据是共享的,因此每个进程“看到”相同的物理内存(在不同的线性地址),假设每个文件的相同版本是共享的。
您可以通过查看maps
每个进程/proc/
目录中的文件来查看各种映射;因为libc
您会看到诸如
7f1014062000-7f10141f7000 r-xp 00000000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f10141f7000-7f10143f7000 ---p 00195000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f10143f7000-7f10143fb000 r--p 00195000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f10143fb000-7f10143fd000 rw-p 00199000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
或者
7f4d7a8ec000-7f4d7aa81000 r-xp 00000000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7aa81000-7f4d7ac81000 ---p 00195000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7ac81000-7f4d7ac85000 r--p 00195000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
7f4d7ac85000-7f4d7ac87000 rw-p 00199000 fd:0d 1444681 /lib/x86_64-linux-gnu/libc-2.24.so
只读、可执行映射对应库中的共享可执行代码;只读映射可以访问库中的共享只读数据;读写映射是库中变量的私有映射。正如您在上面看到的,线性地址是不同的(由于地址空间布局随机化和不同的加载顺序);一旦共享部分加载到内存中,它们的底层物理地址是相同的(因为映射映射底层文件,而不是直接映射共享内存)。