進程的內存空間布局


進程的內存布局在結構上是有規律的,具體來說對於 linux 系統上的進程,其內存空間一般可以粗略地分為以下幾大段【1】,從高內存到低內存排列:

1、內核態內存空間,其大小一般比較固定(可以編譯時調整),但 32 位系統和 64 位系統的值不一樣。

2、用戶態的堆棧,大小不固定,可以用 ulimit -s 進行調整,默認一般為 8M,從高地址向低地址增長。

3、mmap 區域,進程茫茫內存空間里的主要部分,既可以從高地址到低地址延伸(所謂 flexible layout),也可以從低到高延伸(所謂 legacy layout),看進程具體情況【2】【3】。

4、brk 區域,緊鄰數據段(甚至貼着),從低位向高位伸展,但它的大小主要取決於 mmap 如何增長,一般來說,即使是 32 位的進程以傳統方式延伸,也有差不多 1 GB 的空間(准確地說是 TASK_SIZE/3 - 代碼段數據段,參看 arch/x86/include/asm/processor.h 里的定義)【4】

5、數據段,主要是進程里初始化和未初始化的全局數據總和,當然還有編譯器生成一些輔助數據結構等等),大小取決於具體進程,其位置緊貼着代碼段。

6、代碼段,主要是進程的指令,包括用戶代碼和編譯器生成的輔助代碼,其大小取決於具體程序,但起始位置根據 32 位還是 64 位一般固定(-fPIC, -fPIE等除外【5】)。

以上各段(除了代碼段數據段)其起始位置根據系統是否起用 randomize_va_space 一般稍有變化,各段之間因此可能有隨機大小的間隔,千言萬語不如一幅圖(x86-32位下):

32位下bash進程的示例:

【1】https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Tuning_and_Optimizing_Red_Hat_Enterprise_Linux_for_Oracle_9i_and_10g_Databases/sect-Oracle_9i_and_10g_Tuning_Guide-Growing_the_Oracle_SGA_to_2.7_GB_in_x86_Red_Hat_Enterprise_Linux_2.1_Without_VLM-Linux_Memory_Layout.html
【2】understanding the linux kernel, page 819, flexible memory region layout: https://books.google.com.hk/books?id=h0lltXyJ8aIC&pg=PT925&lpg=PT925&dq=linux+flexible+memory&source=bl&ots=gO7rIYb8HR&sig=pirB5pswdHFHSljy57EksxS3ABw&hl=en&sa=X&ved=0ahUKEwjpkfa-2_rRAhVGFJQKHcETDSUQ6AEITDAH#v=onepage&q=linux%20flexible%20memory&f=false
【3】https://gist.github.com/CMCDragonkai/10ab53654b2aa6ce55c11cfc5b2432a4
【4】http://lxr.free-electrons.com/source/arch/x86/include/asm/processor.h#L770
【5】https://access.redhat.com/blogs/766093/posts/1975793


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM