標籤:

進程地址空間

下圖是x86_64下linux進程的默認內存布局形式:

下面逐一分析以上各個地址段的含義。

text 代碼段

代碼段,從虛擬內存地址00400000開始,使用pmap $$可以查看到,這個地址是固定的:

linux # pmap $$n27729: bashnSTART SIZE RSS PSS DIRTY SWAP PERM MAPPINGn00400000 552K 480K 260K 0K 0K r-xp /bin/bashn00689000 4K 4K 4K 4K 0K r--p /bin/bashn0068a000 20K 20K 20K 20K 0K rw-p /bin/bashn0068f000 1420K 1356K 1356K 1356K 0K rw-p [heap]n7f4f47b72000 64K 4K 4K 0K 0K r-xp /usr/lib64/gconv/libGB.son……n7f4f48c33000 4K 4K 4K 4K 0K rw-p [anon]n7fff0f0f1000 84K 20K 20K 20K 0K rw-p [stack]n7fff0f1ff000 4K 4K 0K 0K 0K r-xp [vdso]nffffffffff600000 4K 0K 0K 0K 0K r-xp [vsyscall]nTotal: 18944K 3256K 2225K 1580K 0Kn1652K writable-private, 17052K readonly-private, 240K shared, and 3256K referencedn

00400000地址段用於存放程序的可執行文件,fork一個子進程,之後調用execve載入可執行文件,execve即將文件載入到該段地址中:

linux # strace lsnexecve("/bin/ls", ["ls"], [/* 65 vars */]) = 0nbrk(0) =0x618000nmmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) = 0x7f0422e2a000n……n

data 數據段

數據段用於存放已初始化全局變數。

bss段

該段用於存放全局的、但未初始化的變數。bss段與data段的區別是,編譯時需為data段分配空間,而bss段不用。數據存放於bss段,減小了可執行程序的文件大小。

heap

堆,c庫中的malloc調用就是從該段獲取內存空間。

memory map

mmap系統調用可將文件映射入進程memory map地址空間。使用pmap $$查看,[heap]下面部分就是mmap區域,對於以上"pmap $$"輸出:

7f4f47b72000 64K 4K 4K 0K 0K r-xp /usr/lib64/gconv/libGB.son

bash進程將/usr/lib64/gconv/libGB.so文件映射到以7f4f47b72000開頭的地址段。

使用ldd命令,我們可以看到進程依賴的庫文件,這些庫文件編譯過程中都要關聯到進程的虛擬地址空間:

linux # ldd /bin/bashn linux-vdso.so.1 => (0x00007fffc73ff000)n libreadline.so.5 => /lib64/libreadline.so.5 (0x00007f7effe50000)n libdl.so.2 => /lib64/libdl.so.2 (0x00007f7effc4c000)n libc.so.6 => /lib64/libc.so.6 (0x00007f7eff8ee000)n libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f7eff6a6000)n /lib64/ld-linux-x86-64.so.2 (0x00007f7f00092000)n

stack

存放局部變數,從高地址向低地址生長。

內核代碼中,mm_struct結構用於描述一個進程的地址空間。

vm_area_struct用於描述一段地址,linux提供了/proc/PID/maps介面,我們可以通過該介面查詢某進程的虛擬地址段:

linux # cat /proc/$$/mapsn00400000 - 00486000 r-xp 00000000 08:02 18104 /bin/bashn00586000 - 00586000 rw-p 00086000 08:02 18104 /bin/bashn0058b000 - 0073b000 rw-p 0058b000 00:00 0 [heap]n2b7c1ff67000 - 2b7c1ff82000 r-xp 00000000 08:02 12969 /lib64/ld-2.4.son……n7fff8ab2d000 - 7fff8ab43000 rw-p 7fff8ab2d000 00:00 0 [stack]nffffffffff600000 - ffffffffffe00000 ---p 00000000 00:00 0 [vdso]n

c庫中的malloc底層通過mmap或brk實現內存申請。mmap可用於關聯文件到進程的虛擬地址空間,也可用於申請匿名地址空間。

void *mmap( void *addr, size_t length, int prot, int flags, int fd, off_t offset);n

若指明fd就是關聯文件到虛擬地址空間,沒有指明就是申請匿名地址空間。

brk調用只是增加heap這一段虛擬內存空間,sbrk用於實際的內存申請。

Reference: Chapter 15 - The Process Address Space, Linux kernel development.3rd.Edition


推薦閱讀:

Linux 桌面系統的優勢
Linux 性能診斷:負載評估
遷移到 Linux:磁碟、文件、和文件系統
Linux RAS特性分析
偽造掌閱ireader plus升級的伺服器

TAG:Linux | Linux内核 |