2017-07-19 81 views
-2

當Linux加載共享庫時,我的理解是,文本部分只加載到物理內存中一次,然後映射到引用它的不同進程的頁表中。在物理內存中如何避免共享庫文本部分的多個副本?

但是在哪裏/誰確保/檢查相同的共享庫文本段沒有被多次加載到物理內存中?

是否通過加載程序或mmap()系統調用避免了複製或者有其他方法以及如何實現?

編輯1: 我必須證明迄今爲止做了什麼(研究)。這是...

試圖跟蹤一個簡單的睡眠命令。

$ strace sleep 100 & 
[1] 22824 
$ execve("/bin/sleep", ["sleep", "100"], [/* 26 vars */]) = 0 
brk(0)         = 0x89bd000 
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory) 
open("/etc/ld.so.cache", O_RDONLY)  = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=92360, ...}) = 0 
mmap2(NULL, 92360, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f56000 
close(3)        = 0 
open("/lib/libc.so.6", O_RDONLY)  = 3 
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0`G\0004\0\0\0"..., 512) = 512 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f55000 
fstat64(3, {st_mode=S_IFREG|0755, st_size=1706232, ...}) = 0 
mmap2(0x460000, 1426884, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x460000 
mmap2(0x5b7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x156) = 0x5b7000 
mmap2(0x5ba000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x5ba000 
close(3)        = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f54000 
... 
munmap(0xb7f56000, 92360)    = 0 
... 

然後檢查此過程的/ proc/pid/maps文件;

$ cat /proc/22824/maps 
00441000-0045c000 r-xp 00000000 fd:00 2622360 /lib/ld-2.5.so 
... 
00460000-005b7000 r-xp 00000000 fd:00 2622361 /lib/libc-2.5.so 
... 
00e3e000-00e3f000 r-xp 00e3e000 00:00 0   [vdso] 
08048000-0807c000 r-xp 00000000 fd:00 5681559 /usr/bin/strace 
... 

在這裏可看出,對於mmap2 libc.so.6的與PROT_READ|PROT_EXEC的addr參數()是在一個特定的地址。這使我相信物理內存中的共享庫映射是由加載程序管理的。

+0

Linux內核以及與此問題相關的所有相關係統都是開源的,可以通過它查看源代碼。 –

+0

@Someprogrammerdude這是真的,但任何能夠在內核中檢查它的人都已經很早就學會了它,而每個人都可以好奇,它是如何工作的。 – peterh

回答

0

共享庫由系統調用mmap()加載,並且Linux內核很聰明。它有一個內部數據結構,它將文件描述符(包含安裝實例和inode編號)映射到其中的映射頁面。

動態鏈接器(它的代碼是/lib/ld-linux.so或類似的地方)只使用這個mmap()調用映射這些庫(然後重新定位它們的符號表),這個頁面級重複數據刪除完全由內核完成。

的映射發生與PROT_READ|PROT_EXEC|PROT_SHARED標誌,你可以很容易地通過stracing任何工具(如strace /bin/echo)檢查。

+0

對文件描述符和inode編號的引用是我正在尋找的。謝謝 – emilk

+0

我的榮幸:-)如果答案解決了您的問題,您可以通過點擊左側的管道圖標來接受它。這對回答者來說是一種回報,對未來的訪客來說,問題已經解決了。 – peterh

相關問題