編寫動態連接庫有什麼好處呢。
linux
對於linux來講,若是一個代碼量龐大的程序,若是在系統中會存在不少個程序實例。這個時候,將部分代碼實如今動態連接庫中就有節省內存的好處。
函數
這裏介紹一個工具叫作,strace,能夠用來跟蹤程序的系統調用,對於常常奔潰的程序來講,調試時頗有用處。工具
對於一個簡單的printf()程序:
調試
int main()
code
{
進程
printf("hello \n");
內存
return 1;
it
}
class
對上述程序用 strace進行啓動獲得輸出:
file
execve("./a.out", ["./a.out"], [/* 19 vars */]) = 0 brk(0) = 0x199e000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f68e0141000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=70103, ...}) = 0 mmap(NULL, 70103, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f68e012f000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\30\2\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0 mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f68dfb61000 mprotect(0x7f68dfd16000, 2097152, PROT_NONE) = 0 mmap(0x7f68dff16000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f68dff16000 mmap(0x7f68dff1c000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f68dff1c000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f68e012e000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f68e012d000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f68e012c000 arch_prctl(ARCH_SET_FS, 0x7f68e012d700) = 0 mprotect(0x7f68dff16000, 16384, PROT_READ) = 0 mprotect(0x600000, 4096, PROT_READ) = 0 mprotect(0x7f68e0143000, 4096, PROT_READ) = 0 munmap(0x7f68e012f000, 70103) = 0 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f68e0140000 write(1, "hi\n", 3hi ) = 3 exit_group(1) = ?
能夠看出在調用printf的過程當中,打開libc以後,調用了mmap把文件的內容映射到了進程的空間當中,當系統中有多個程序實例須要引用libc的時候他們共享的內存是同一份,因此使用動態連接庫是能夠節省內存的。
還能夠看出printf的底層實現是write函數。