linux內存管理機制(自己整理)


1、以程序開發者的角度審視Linux的進程內存管理

2、系統物理內存管理和內核內存的使用方法

3、內存映射、理解內核內存管理與用戶內存管理之間的關系

進程與內存

進程如何使用內存?

毫無疑問,所有進程(執行的程序)都必須占用一定數量的內存,它或是用來存放從磁盤載入的程序代碼,或是存放取自用戶輸入的數據等等。不過進程對這些內存的管理方式因內存用途不一而不盡相同,有些內存是事先靜態分配和統一回收的,而有些卻是按需要動態分配和回收的。

對任何一個普通進程來講,它都會涉及到5種不同的數據段。稍有編程知識的朋友都能想到這幾個數據段中包含有“程序代碼段”、“程序數據段”、“程序堆棧段”等。不錯,這幾種數據段都在其中,但除了以上幾種數據段之外,進程還另外包含兩種數據段。下面我們來簡單歸納一下進程對應的內存空間中所包含的5種不同的數據區。

代碼段:代碼段是用來存放可執行文件的操作指令,也就是說是它是可執行程序在內存中的鏡像。代碼段需要防止在運行時被非法修改,所以只准許讀取操作,而不允許寫入(修改)操作——它是不可寫的。

數據段:數據段用來存放可執行文件中已初始化全局變量,換句話說就是存放程序靜態分配[1]的變量和全局變量。

BSS段:BSS段包含了程序中未初始化的全局變量,在內存中 bss段全部置零。

堆(heap):堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)

:棧是用戶存放程序臨時創建的局部變量,也就是說我們函數括弧“{}”中定義的變量(但不包括static聲明的變量,static意味着在數據段中存放變量)。除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束后,函數的返回值也會被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來保存/恢復調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的內存區。

進程如何組織這些區域?

上述幾種內存區域中數據段、BSS和堆通常是被連續存儲的——內存位置上是連續的,而代碼段和棧往往會被獨立存放。有趣的是,堆和棧兩個區域關系很“曖昧”,他們一個向下“長”(i386體系結構中棧向下、堆向上),一個向上“長”,相對而生。但你不必擔心他們會碰頭,因為他們之間間隔很大(到底大到多少,你可以從下面的例子程序計算一下),絕少有機會能碰到一起。

進入操作系統內核看看,進程對內存具體是如何進行分配和管理的。

從用戶向內核看,所使用的內存表象形式會依次經歷“邏輯地址”——“線性地址”——“物理地址”幾種形式。邏輯地址經段機制轉化成線性地址;線性地址又經過頁機制轉化為物理地址。(但是我們要知道Linux系統雖然保留了段機制,但是將所有程序的段地址都定死為0-4G,所以雖然邏輯地址和線性地址是兩種不同的地址空間,但在Linux中邏輯地址就等於線性地址,它們的值是一樣的)。沿着這條線索,我們所研究的主要問題也就集中在下面幾個問題。

1.     進程空間地址如何管理?

2.     進程地址如何映射到物理內存?

3.     物理內存如何被管理?

進程內存空間

Linux操作系統采用虛擬內存管理技術,使得每個進程都有各自互不干涉的進程地址空間。該空間是塊大小為4G的線性虛擬空間,用戶所看到和接觸到的都是該虛擬地址,無法看到實際的物理內存地址。利用這種虛擬地址不但能起到保護操作系統的效果(用戶不能直接訪問物理內存),而且更重要的是,用戶程序可使用比實際物理內存更大的地址空間。

在討論進程空間細節前,這里先要澄清下面幾個問題:

一、4G的進程地址空間被人為的分為兩個部分——用戶空間內核空間。用戶空間從0到3G(0xC0000000),內核空間占據3G到4G。用戶進程通常情況下只能訪問用戶空間的虛擬地址,不能訪問內核空間虛擬地址。只有用戶進程進行系統調用(代表用戶進程在內核態執行)等時刻可以訪問到內核空間。

二、用戶空間對應進程,所以每當進程切換,用戶空間就會跟着變化;而內核空間是由內核負責映射它並不會跟着進程改變,是固定的。內核空間地址有自己對應的頁表(init_mm.pgd),用戶進程各自有不同的頁表

三、每個進程的用戶空間都是完全獨立、互不相干的。不信的話,你可以把上面的程序同時運行10次(當然為了同時運行,讓它們在返回前一同睡眠100秒吧),你會看到10個進程占用的線性地址一模一樣。


免責聲明!

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



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