從Linux看虛擬地址空間

程序地址空間

我們先看一下一般的程序地址空間(假設是32位下的操作系統4G內存):
在這裏插入圖片描述
接下來我們看一段有意思的代碼:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int gval=100;//定義一個全局變量
int main()
{
        pid_t pid=fork();//創建子進程
        if(pid==0)
        {
                gval=10;//在子進程中對全局變量進行修改
                printf("this is child:%d-gval=%d\n-%p\n",pid,gval,&gval);
        }
        else if(pid>0)
        {
                sleep(2);
                printf("this is parent:%d-gval=%d\n-%p\n",pid,gval,&gval);
        }
        return 0;
}

大家會覺得結果 gval 會是10 ,結果如下:
在這裏插入圖片描述
可以看到子進程的確是將gval修改成了10 但是父進程依然打印出的gval 是100 ,並且大家可以發現兩個變量的地址確實相同的?

變量:像是一塊空間的別名,通過別名可以訪問空間中的內容
空間:用來存儲數據的,一塊空間只會存儲一個數據
在我們中的程序中發現一個全局變量在父子進程中的數據時不一樣的,一塊空間值能存儲一個數據,表明父子gval變量用的肯定不是同一個空間 但是經過打印發現,地址也是一樣的

提出疑問:難道同一個空間同時存儲了兩個變量gval 一個是10 另一個是100?
當然這是不可能的!那麼如何解釋這個現象呢?
這裏提出一個問題,我們打印出來的地址就是實際的物理地址嗎?並不是,因此引入虛擬地址空間的概念。

虛擬地址空間

內存地址:對內存區域的編號,用過編號就可以尋找到相應的空間
實際上我們在進程中所看到的地址都是虛擬地址,而不是物理內存的單位編號
我們所說的程序地址空間實際上是一個虛擬地址空間

虛擬地址空間到底是什麼?
實際上虛擬地址空間是操作系統給進程描述的一個虛假的地址空間

比如說我們使用的某盤–某盤說給每個人免費的都有1G空間甚至說有5 G 100G的空間,據調查中國有接近9億的網民,它爲什麼敢說給每人那麼多空間呢

其實通過虛擬地址空間,可以給進程造成一個假象:我有連續的,完整的內存使用
虛擬地址空間操作系統通過一個struct mm_struct 結構描述的虛擬空間;就是虛擬的編號

比如一張桌子是1m 然後你和你的同桌進行劃分 0-80 是你的 20- 100是你同桌的 看似兩個人同同時擁有了80釐米的空間但是其實是虛擬的

爲什麼要使用虛擬地址空間:例如:
在這裏插入圖片描述

操作系統中的內存管理方式: 分段式/分頁式 /段頁式

先分配虛擬地址還是分配物理內存?:
先分配虛擬地址,然後再將數據存儲在物理內存,當申請空間但不佔用空間時(不進行數據存儲),只開一個空頭支票,當要存儲數據的時候再進行物理內存的分配

分段式:將地址空間進行分段 ,代碼段/數據段/堆/棧/參數/環境變量

根據使用一個空間的性質,在不同的分段,分配虛擬地址,有助於編譯器的內存管理

虛擬地址的組成:段號+段內的偏移量
在操作系統中有一個段表,表中包含:虛擬段號,物理內存段起始地址
段表:
在這裏插入圖片描述
通過虛擬地址中的段號,在段表中找到相應的段表項,得到物理段起始地址,加上段內偏移最終得到物理地址

但是這樣的話還是會有很多的內存碎片

分頁式內存管理:

虛擬地址的組成:頁號+頁內偏移量
在操作系統中有一個頁表,頁表中包含:虛擬頁號,物理塊號,內存訪問控制標誌,缺頁中斷位

在這裏插入圖片描述
分頁式內存管理主要實現數據在物理內存上的離散式存儲以及頁面的訪問控制

頁內偏移佔多少個字節取決於頁面的大小 例如一個頁面時4096個字節的話 佔低12 位 因爲 2^12=4096
其他的爲頁號所佔的位數

段頁式:在分段的基礎上,每個分段內進行分頁式管理 (現在電腦所使用的)

地址組成:段號-段內頁號-頁內偏移
通過段號在段表中找到內存段對應的頁表地址 ,根據地址找到頁表 ,通過段內頁號找到頁表項,得到物理起始地址(或者物理塊號)加上頁內偏移
段表中包含:段號+段內頁表起始地址 頁表包含:頁號+頁內偏移

其實瞭解了這些,我們可以知道,雖然打印出的地址是相同的,但是其實實際的物理地址是不同的,爲子進程又重新開闢了空間,存儲了變量gval.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章