LINUX系統程式設計 LINUX 虛擬記憶體
LINUX 虛擬記憶體
以32位作業系統為例子,因為64位系統虛擬地址過大為2^64,32位僅僅為2^32=4G更利於描述,但是原理東西都一樣
這首先要從程式和程式之間的關係開始,我們一般寫好一段C\C++程式碼編譯後僅僅為可執行檔案假設為a.out,我們
執行a.out的時候,這個才叫程式,程式是OS級別抽象的實體(PCB task_struct結構體),為程式執行進行各種檢查和
系統資源分配,一個PCB包含部分資訊如下:
(摘至刑文鵬LINUX系統程式設計講義)
* 程式id。系統中每個程式有唯一的id,在C語言中用pid_t型別表示,其實就是一個非
負整數。
* 程式的狀態,有執行、掛起、停止、殭屍等狀態。
* 程式切換時需要儲存和恢復的一些CPU暫存器。
* 描述虛擬地址空間的資訊。
* 描述控制終端的資訊。
* 當前工作目錄(Current Working Directory)。
* umask掩碼。
* 檔案描述符表,包含很多指向file結構體的指標。
* 和訊號相關的資訊。
* 使用者id和組id。
* 控制終端、Session和程式組。
* 程式可以使用的資源上限(Resource Limit)
每個程式分配的記憶體包含很多稱之為段的部分組成並且放到0-3G使用者態虛擬地址空間中,3-4G為kernel太虛擬地址(注意我們以32位為列),
PCB就存放在我們的kernel態中。
下面描述0-3G使用者態虛擬記憶體段
由下向上分別是
1、程式碼段,是程式執行的機器程式碼,一個程式程式碼可以多個程式
同時執行,那麼這個程式碼段可以同時存在於不同程式的不同
虛擬記憶體地址中,等會用圖說明
2、初始化資料段,這個就是C\C++已經初始化的全域性變數和靜態變數
我們知道靜態變數是存在於程式結束,而全域性變數(非靜態)的作用
域也是全部程式碼塊,那麼這些變數需要放到一個非棧空間中
(關於靜態變數可以檢視如下連結
http://blog.itpub.net/7728585/viewspace-2119670/
)
3、未初始化資料段,為初始化的全域性變數和靜態變數,未初始化本
段的內容初始化為0
4、堆(heap)段,是在執行的時候動態程式分配的記憶體區域,比如malloc
下面以一段簡單程式碼說明,目的僅僅在於說明上面說的:
(未分配虛擬記憶體地址)
5、棧(stack)段,我們知道棧是一個後進先出的資料結構,用於儲存區域性
變數,實參和返回值。它由棧幀組成(stack frames),每次新的函式呼叫
都會分配一個新的棧幀比如下面的getv rev都在main函式棧幀裡面。
而沒有使用到區域性變數t 則在add函式棧幀裡面
6、argc,environ 陣列資訊,固定大小
本來很多影像自己畫,但是發現比較麻煩,並且效果可能並不如原圖好,所以直接
摘錄.
關於程式各段組織如下(摘自UNIX/LINUX系統程式設計手冊)
關於程式使用者態和核心態的關係如下(摘自刑文鵬LINUX系統程式設計講義)
為了方便管理LINUX將記憶體分為叫做頁幀的單元(我們熟悉的4K),然後核心中就需要儲存一份程式虛擬地址到實際地址的對映表,如果訪問的資料不再實體記憶體
中就發生page fault,將磁碟中的資料複製到實體記憶體,建立虛擬地址到實體記憶體的對映關係,一個程式訪問資料是透過虛擬地址進行訪問,然後透過對映表對應
到實際的實體記憶體。
由於64位系統需要管理的記憶體頁非常巨大在LINUX中使用三級或者四級(核心2.6.11以上使用四級)對映表,關於對映表實際實現這裡沒有過多討論,因為這個屬於
LINUX核心原理的東西,我也沒有能力研究。
(實際是虛擬地址--》線性地址--》實體地址,但是LINUX中虛擬地址和線性地址是相同的。)
對映表直觀圖(摘自UNIX/LINUX系統程式設計手冊)
四級對映表(摘自pdf記憶體定址)
最後我們需要牢牢的記住的就是每個程式都有0-4G的虛擬地址空間可供分配,當然沒有分配就是未使用的,程式訪問的是記憶體虛擬地址,虛擬地址空間的資料可能並不
在實際記憶體中,當程式訪問到虛擬地址的資料並不在記憶體中,那麼發生page fault,將磁碟中的資料複製到實體記憶體,建立虛擬地址到實體記憶體的對映關係,如果在實際記憶體不足的情況下啟用swap做為實體記憶體的補充,將部分曾經使用過的資料而當前沒有使用的資料複製到SWAP中。而資料的過期處理一般為使用者程式自己控制比如LRU連結串列。
(這也是為什麼某些資料庫比如ORACLE MYSQL,在一臺64G的記憶體的機器上同時跑2個例項都分配64G左右記憶體能夠起來,但是過一段時間可能報記憶體不足的原因)
某些觀點為作者自己觀點如果有誤請指出
參考資料:
1、UNIX/LINUX系統程式設計手冊
2、LINUX作業系統原理與應用
3、刑文鵬LINUX系統程式設計講義
4、pdf記憶體定址
以32位作業系統為例子,因為64位系統虛擬地址過大為2^64,32位僅僅為2^32=4G更利於描述,但是原理東西都一樣
這首先要從程式和程式之間的關係開始,我們一般寫好一段C\C++程式碼編譯後僅僅為可執行檔案假設為a.out,我們
執行a.out的時候,這個才叫程式,程式是OS級別抽象的實體(PCB task_struct結構體),為程式執行進行各種檢查和
系統資源分配,一個PCB包含部分資訊如下:
(摘至刑文鵬LINUX系統程式設計講義)
* 程式id。系統中每個程式有唯一的id,在C語言中用pid_t型別表示,其實就是一個非
負整數。
* 程式的狀態,有執行、掛起、停止、殭屍等狀態。
* 程式切換時需要儲存和恢復的一些CPU暫存器。
* 描述虛擬地址空間的資訊。
* 描述控制終端的資訊。
* 當前工作目錄(Current Working Directory)。
* umask掩碼。
* 檔案描述符表,包含很多指向file結構體的指標。
* 和訊號相關的資訊。
* 使用者id和組id。
* 控制終端、Session和程式組。
* 程式可以使用的資源上限(Resource Limit)
每個程式分配的記憶體包含很多稱之為段的部分組成並且放到0-3G使用者態虛擬地址空間中,3-4G為kernel太虛擬地址(注意我們以32位為列),
PCB就存放在我們的kernel態中。
下面描述0-3G使用者態虛擬記憶體段
由下向上分別是
1、程式碼段,是程式執行的機器程式碼,一個程式程式碼可以多個程式
同時執行,那麼這個程式碼段可以同時存在於不同程式的不同
虛擬記憶體地址中,等會用圖說明
2、初始化資料段,這個就是C\C++已經初始化的全域性變數和靜態變數
我們知道靜態變數是存在於程式結束,而全域性變數(非靜態)的作用
域也是全部程式碼塊,那麼這些變數需要放到一個非棧空間中
(關於靜態變數可以檢視如下連結
http://blog.itpub.net/7728585/viewspace-2119670/
)
3、未初始化資料段,為初始化的全域性變數和靜態變數,未初始化本
段的內容初始化為0
4、堆(heap)段,是在執行的時候動態程式分配的記憶體區域,比如malloc
下面以一段簡單程式碼說明,目的僅僅在於說明上面說的:
(未分配虛擬記憶體地址)
5、棧(stack)段,我們知道棧是一個後進先出的資料結構,用於儲存區域性
變數,實參和返回值。它由棧幀組成(stack frames),每次新的函式呼叫
都會分配一個新的棧幀比如下面的getv rev都在main函式棧幀裡面。
而沒有使用到區域性變數t 則在add函式棧幀裡面
6、argc,environ 陣列資訊,固定大小
點選(此處)摺疊或開啟
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<string.h>
-
-
typedef unsigned int uint;
-
-
static uint step=1024;//全域性初始化靜態變數,初始化資料段
-
uint iniv=1; //全域性初始化非靜態變數,可以使用extern訪問,初始化資料段
-
-
static uint zero;//全域性未初始化靜態變數,未初始化資料段
-
-
-
uint add(uint inv) //值傳遞 棧 for add funcation stack frame
-
{
- int t; // 棧 for add funcation stack frames
-
return inv*step+zero; //棧 for add funcation stack frames
-
}
-
-
-
int main(void)
-
{
-
uint getv = 10; //棧 for main funcation stack frame
-
uint rev; //棧 for main funcation stack frames
-
-
char* p; //棧 for main funcation stack frames
-
-
rev = add(getv);
-
p = calloc(6,1); //堆
-
strcpy(p,"test:");
-
printf("%s%u\n",p,rev);
-
return 0;
- }
摘錄.
關於程式各段組織如下(摘自UNIX/LINUX系統程式設計手冊)
關於程式使用者態和核心態的關係如下(摘自刑文鵬LINUX系統程式設計講義)
為了方便管理LINUX將記憶體分為叫做頁幀的單元(我們熟悉的4K),然後核心中就需要儲存一份程式虛擬地址到實際地址的對映表,如果訪問的資料不再實體記憶體
中就發生page fault,將磁碟中的資料複製到實體記憶體,建立虛擬地址到實體記憶體的對映關係,一個程式訪問資料是透過虛擬地址進行訪問,然後透過對映表對應
到實際的實體記憶體。
由於64位系統需要管理的記憶體頁非常巨大在LINUX中使用三級或者四級(核心2.6.11以上使用四級)對映表,關於對映表實際實現這裡沒有過多討論,因為這個屬於
LINUX核心原理的東西,我也沒有能力研究。
(實際是虛擬地址--》線性地址--》實體地址,但是LINUX中虛擬地址和線性地址是相同的。)
對映表直觀圖(摘自UNIX/LINUX系統程式設計手冊)
四級對映表(摘自pdf記憶體定址)
最後我們需要牢牢的記住的就是每個程式都有0-4G的虛擬地址空間可供分配,當然沒有分配就是未使用的,程式訪問的是記憶體虛擬地址,虛擬地址空間的資料可能並不
在實際記憶體中,當程式訪問到虛擬地址的資料並不在記憶體中,那麼發生page fault,將磁碟中的資料複製到實體記憶體,建立虛擬地址到實體記憶體的對映關係,如果在實際記憶體不足的情況下啟用swap做為實體記憶體的補充,將部分曾經使用過的資料而當前沒有使用的資料複製到SWAP中。而資料的過期處理一般為使用者程式自己控制比如LRU連結串列。
(這也是為什麼某些資料庫比如ORACLE MYSQL,在一臺64G的記憶體的機器上同時跑2個例項都分配64G左右記憶體能夠起來,但是過一段時間可能報記憶體不足的原因)
某些觀點為作者自己觀點如果有誤請指出
參考資料:
1、UNIX/LINUX系統程式設計手冊
2、LINUX作業系統原理與應用
3、刑文鵬LINUX系統程式設計講義
4、pdf記憶體定址
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14710393/viewspace-2131124/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux 虛擬記憶體Linux記憶體
- Linux系統程式設計—共享記憶體之mmapLinux程式設計記憶體
- Linux 虛擬記憶體引數配置Linux記憶體
- 詳細理解Linux虛擬記憶體Linux記憶體
- Linux系統程式設計之命名管道與共享記憶體Linux程式設計記憶體
- Linux設定虛擬記憶體教學和實戰Linux記憶體
- 為什麼 Linux 需要虛擬記憶體Linux記憶體
- linux伺服器增加虛擬記憶體Linux伺服器記憶體
- win11系統設定虛擬記憶體記憶體
- Linux 程式設計1:深入淺出 Linux 共享記憶體Linux程式設計記憶體
- 計算機作業系統——虛擬記憶體與實體記憶體計算機作業系統記憶體
- linux系統使用vmstat命令顯示虛擬記憶體狀態的方法教程Linux記憶體
- PostgreSQL 原始碼解讀(229)- Linux Kernel(程式虛擬記憶體#3)SQL原始碼Linux記憶體
- PostgreSQL 原始碼解讀(227)- Linux Kernel(程式虛擬記憶體#2)SQL原始碼Linux記憶體
- Linux系統程式設計之程式間通訊方式:共享記憶體例項演示Linux程式設計記憶體
- 虛擬記憶體系統——瞭解記憶體的工作原理記憶體
- PostgreSQL 原始碼解讀(226)- Linux Kernel(虛擬記憶體)SQL原始碼Linux記憶體
- Linux記憶體不夠了?看看如何開啟虛擬記憶體增加記憶體使用量Linux記憶體
- 【原創】Linux虛擬化KVM-Qemu分析(五)之記憶體虛擬化Linux記憶體
- Linux記憶體子系統——Locking Pages(記憶體鎖定)Linux記憶體
- Win10系統C盤虛擬記憶體怎麼設定?Win10專業版系統C盤虛擬記憶體設定方法Win10記憶體
- win10怎麼加虛擬記憶體_win10系統增加虛擬記憶體教程Win10記憶體
- 【Linux】Linux系統程式設計入門Linux程式設計
- windows10系統如何增加虛擬記憶體Windows記憶體
- Linux作業系統記憶體淺析Linux作業系統記憶體
- 【Linux系統程式設計】Linux訊號列表Linux程式設計
- win10怎麼清除虛擬記憶體 win10系統虛擬記憶體清理的辦法Win10記憶體
- 在Linux中,什麼是虛擬記憶體?它是如何工作的?Linux記憶體
- win10虛擬記憶體怎麼設定 win10虛擬記憶體設定方法Win10記憶體
- win10 虛擬記憶體怎麼設定好 win10 虛擬記憶體設定方法Win10記憶體
- 怎麼設定虛擬記憶體win10 win10虛擬記憶體如何設定記憶體Win10
- win10 8g記憶體還需要虛擬記憶體嗎 win10系統8g記憶體怎麼分配虛擬記憶體Win10記憶體
- win10系統4g的記憶體設定多大的虛擬記憶體合適Win10記憶體
- win10系統16g記憶體推薦虛擬記憶體設定多少合適Win10記憶體
- 聊聊虛擬記憶體記憶體
- Linux雲端計算技術學習:虛擬機器堆記憶體結構Linux虛擬機記憶體
- (2)Linux效能調優之Linux記憶體體系Linux記憶體
- win10系統下設定虛擬記憶體初始大小的方法Win10記憶體
- 如何檢視linux系統中空閒記憶體/實體記憶體使用/剩餘記憶體Linux記憶體