資源描述:
《【精品】Linux內(nèi)存管理》由會員上傳分享,免費在線閱讀,更多相關內(nèi)容在工程資料-天天文庫。
1、Linux內(nèi)存管理(一)2010-10-0410:03轉(zhuǎn)載自nkd2002最終編輯nkd2002木文轉(zhuǎn)貼自:http:〃Hww.kerneltravel,net/jouriial/v/mem.htm摘要:本章首先以應用程序開發(fā)者的角度審視Linux的進程內(nèi)存管理,在此基礎上逐步深入到內(nèi)核中討論系統(tǒng)物理內(nèi)存管理和內(nèi)核內(nèi)存的使用方法。力求從外到內(nèi)、水到渠成地引導網(wǎng)友分析Linux的內(nèi)存管理與使用。在本章最后,我們給出一個內(nèi)存映射的實例,幫助網(wǎng)友們理解內(nèi)核內(nèi)存管理與用戶內(nèi)存管理之間的關系,希望大家最終能駕馭
2、Linux內(nèi)存管理。刖呂內(nèi)存管理一向是所有操作系統(tǒng)書籍不惜筆墨重點討論的內(nèi)容,無論市面上或是網(wǎng)上都充斥著大屋涉及內(nèi)存管理的教材和資料。因此,我們這里所要寫的Linux內(nèi)存管理采収避重就輕的策略,從理論層面就不去班門弄斧,貽笑大方了。我們最想做的和町能做到的是從開發(fā)者的角度談談對內(nèi)存管理的理解,最終目的是把我們在內(nèi)核開發(fā)中使用內(nèi)存的經(jīng)驗利對Linux內(nèi)存管理的認識與大家共享。當然,這其中我們也會涉及到一些諸如段頁等內(nèi)存管理的基本理論,但我們的目的不是為了強調(diào)理論,而是為了指導理解開發(fā)中的實踐,所以僅僅點
3、到為止,不做深究。遵循“理論來源于實踐”的“教條”,我們先不必一下了就鉆入內(nèi)核里去看系統(tǒng)內(nèi)存到底是如何管理,那樣往往會讓你陷入似懂非懂的窘境(我當年就犯了這個錯誤?。?。所以最好的方式是先從外部(用戶編程范疇)來觀察進程如何使用內(nèi)存,等到大家對內(nèi)存的使用有了較直觀的認識后,再深入到內(nèi)核中去學習內(nèi)存如何被管理等理論知識。最后再通過一個實例編程將所講內(nèi)容融會貫通。進程與內(nèi)存進程如何使用內(nèi)存?毫無疑問,所有跡程(執(zhí)行的程序)都必須占用一定數(shù)量的內(nèi)存,它或是用來存放從磁盤載入的程序代碼,或是存放取自川戶輸入的數(shù)
4、據(jù)等等。不過進程對這些內(nèi)存的管理方式因內(nèi)存用途不一而不盡相同,仃些內(nèi)存是事先靜態(tài)分配和統(tǒng)一冋收的,而有些卻是按需要動態(tài)分配和冋收的。對任何?個普通進程來講,它都會涉及到5種不同的數(shù)據(jù)段。稍有編程知識的刖友都能想到這兒個數(shù)據(jù)段中包含有“程序代碼段”、“程序數(shù)據(jù)段”、“程序堆棧段”等。不錯,這幾種數(shù)據(jù)段都在其中,但除了以上幾種數(shù)據(jù)段Z外,進程還另外包含兩種數(shù)據(jù)段。下面我們來簡單歸納一下進程對應的內(nèi)存空間中所包含的5種不同的數(shù)據(jù)區(qū)。代碼段:代碼段是用來存放可執(zhí)行文件的操作指令,也就是說是它是町執(zhí)行程序在內(nèi)存
5、屮的鏡像。代碼段需要防止在運行時被非法修改,所以只準許讀取操作,而不允許寫入(修改)操作——它是不可寫的。數(shù)據(jù)段:數(shù)據(jù)段用來存放可執(zhí)行文件屮已初始化全局變量,換句話說就是存放程序靜態(tài)分配1[1]的變量和全局變量。BSS^2[2]:BSS段包含了程序中未初始化的全局變量,在內(nèi)存屮bss段全部置零。堆(heap):堆是用于存放進程運行中被動態(tài)分配的內(nèi)存段,它的人小并不固定,可動態(tài)擴張或縮減。當進秤?調(diào)MJmalloc等換數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張);當利川free等函數(shù)釋放內(nèi)存
6、時,被釋放的內(nèi)存從堆中被剔除(堆被縮減)棧:棧是用八存放程序臨時創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“{}”中定義的變量(但不包括static聲明的變量,static意味著在數(shù)據(jù)段屮心放變量)。除此以外,在函數(shù)被調(diào)用時,其參數(shù)也會被壓入發(fā)起調(diào)用的進程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返冋值也會被存放冋棧中。由于棧的先進先出特點,所以棧特別方便用來保存/恢復調(diào)用現(xiàn)場。從這個意義上講,我們可以把堆??闯梢粋€寄存、交換臨時數(shù)據(jù)的內(nèi)存區(qū)。進程如何組織這些區(qū)域?上述幾種內(nèi)存區(qū)域中數(shù)據(jù)段、BSS和堆通常是被連續(xù)存儲
7、的——內(nèi)存位置上是連續(xù)的,而代碼段和棧往往會被獨立存放。有趣的是,堆和棧兩個區(qū)域關系很“曖味”,他們一個向下“長”(1386體系結(jié)構(gòu)中棧向下、堆向上),一個向上“長”,相對而生。但你不必擔心他們會碰頭,因為他們Z間間隔很大(到底大到多少,你可以從下面的例子程序計算一下),絕少有機會能碰到一起。(首先町以簡化一個概念,i386=Intel80386。其實i386通常被用來作為對Intel(英特爾)32位微處理器的統(tǒng)稱。WindowsNT類系統(tǒng)的安裝盤上,通常i386是其根上的一個文件夾,里面包含了便件所
8、需的基本安裝信息。Windows2000和WindowsXP的安裝文件夾都是1386,止常情況下在安裝泄盤下町以找到這個文件夾。為了加快安裝速度,在安裝前,安裝程序會將i386拷貝到硬盤上。這個文件夾也町以在將來系統(tǒng)發(fā)牛變化(增減新的硬件)吋安裝驅(qū)動程序,或者增加系統(tǒng)附帯的服務組件、軟件時使用。在其它牽涉到處理器說明的地方,通常也可以使用i386這個稱謂,其實和遊作為PowerPC微處理器的縮寫是類似的。但是,現(xiàn)在很多人都是用的Ghost進行的系統(tǒng)安裝,