(轉載)深入理解Linux中內存管理---分段與分頁簡介

首先,必須要闡述一下這篇文章的主題是Linux內存管理中的分段和分頁技術。

來回顧一下歷史,在早期的計算機中,程序是直接運行在物理內存上的。換句話說,就是程序在運行的過程中訪問的都是物理地址。如果這個系統只運行一個程序,那么只要這個程序所需的內存不要超過該機器的物理內存就不會出現問題,也就不需要考慮內存管理這個麻煩事了,反正就你一個程序,就這么點內存,吃不吃得飽那是你的事情了。然而現在的系統都是支持多任務,多進程的,這樣CPU以及其他硬件的利用率會更高,這個時候就要考慮到將系統內有限的物理內存如何及時有效的分配給多個程序了,這個事情本身就稱之為內存管理。

下面舉一個早期的計算機系統中,內存分配管理的例子,以便于大家理解。

加入三個程序,程序1,2,3.程序1運行的過程中需要10M內存,程序2運行的過程中需要100M內存,而程序3運行的過程中需要20M內存。如果系統同時需要運行程序A和B,那么早期的內存管理過程大概是這樣的,將物理內存的前10M分配給A, 接下來的10M-110M分配給B。這種內存管理的方法比較直接,好了,假設這個時候想讓程序C也運行,同時假設系統的內存只有128M,顯然按照這種方法程序C由于內存不夠是不能夠運行的。大家知道可以使用虛擬內存的技術,內存空間不夠的時候可以將程序不需要用到的數據交換到磁盤空間上去,已達到擴展內存空間的目的。下面來看看這種內存管理方式存在的幾個比較明顯的問題。就像文章一開始提到的,要很深層次的把握某個技術最好搞清楚其發展歷程。

1.進程地址空間不能隔離

由于程序直接訪問的是物理內存,這個時候程序所使用的內存空間不是隔離的。舉個例子,就像上面說的A的地址空間是0-10M這個范圍內,但是如果A中有一段代碼是操作10M-128M這段地址空間內的數據,那么程序B和程序C就很可能會崩潰(每個程序都可以系統的整個地址空間)。這樣很多惡意程序或者是木馬程序可以輕而易舉的破快其他的程序,系統的安全性也就得不到保障了,這對用戶來說也是不能容忍的。

2. 內存使用的效率低

如上面提到的,如果要像讓程序A、B、C同時運行,那么唯一的方法就是使用虛擬內存技術將一些程序暫時不用的數據寫到磁盤上,在需要的時候再從磁盤讀回內存。這里程序C要運行,將A交換到磁盤上去顯然是不行的,因為程序是需要連續的地址空間的,程序C需要20M的內存,而A只有10M的空間,所以需要將程序B交換到磁盤上去,而B足足有100M,可以看到為了運行程序C需要將100M的數據從內存寫到磁盤,然后在程序B需要運行的時候再從磁盤讀到內存,知道IO操作比較耗時,所以這個過程效率將會十分低下。

3. 程序運行的地址不能確定

程序每次需要運行時,都需要在內存中非配一塊足夠大的空閑區域,而問題是這個空閑的位置是不能確定的,這會帶來一些重定位的問題,重定位的問題確定就是程序中引用的變量和函數的地址,如果有不明白童鞋可以去查查編譯愿意方面的資料。

內存管理無非就是想辦法解決上面三個問題,如何使進程的地址空間隔離,如何提高內存的使用效率,如何解決程序運行時的重定位問題?

這里引用計算機界一句無從考證的名言:“計算機系統里的任何問題都可以靠引入一個中間層來解決。”

現在的內存管理方法就是在程序和物理內存之間引入了虛擬內存這個概念。虛擬內存位于程序和屋里內存之間,程序只能看見虛擬內存,再也不能直接訪問物理內存。每個程序都有自己獨立的進程地址空間,這樣就做到了進程隔離。這里的進程地址空間是指虛擬地址。顧名思義既然是虛擬地址,也就是虛的,不是現實存在的地址空間。

既然在程序和物理地址空間之間增加了虛擬地址,那么就要解決怎么從虛擬地址映射到物理地址,因為程序最終肯定是運行在物理內存中的,主要有分段和分頁兩種技術。

分段(Segmentation):這種方法是人們最開始使用的一種方法,基本思路是將程序所需要的內存地址空間大小的虛擬空間映射到某個
物理地址空間。

段映射機制

每個程序都有其獨立的虛擬的獨立的進程地址空間,可以看到程序A和B的虛擬地址空間都是從0x00000000開始的。將兩塊大小相同的虛擬地址空間和實際物理地址空間一一映射,即虛擬地址空間中的每個字節對應于實際地址空間中的每個字節,這個映射過程由軟件來設置映射的機制,實際的轉換由硬件來完成。

這種分段的機制解決了文章一開始提到的3個問題中的進程地址空間隔離和程序地址重定位的問題。程序A和程序B有自己獨立的虛擬地址空間,而且該虛擬地址空間被映射到了互相不重疊的物理地址空間,如果程序A訪問虛擬地址空間的地址不在0x00000000-0x00A00000這個范圍內,那么內核就會拒絕這個請求,所以它解決了隔離地址空間的問題。應用程序A只需要關心其虛擬地址空間0x00000000-0x00A00000,而其被映射到哪個物理地址無需關心,所以程序永遠按照這個虛擬地址空間來放置變量,代碼,不需要重新定位。

無論如何分段機制解決了上面兩個問題,是一個很大的進步,但是對于內存效率問題仍然無能為力。因為這種內存映射機制仍然是以程序為單位,當內存不足時仍然需要將整個程序交換到磁盤,這樣內存使用的效率仍然很低。那么,怎么才算高效率的內存使用呢。事實上,根據程序的局部性運行原理,一個程序在運行的過程當中,在某個時間段內,只有一小部分數據會被經常用到。所以需要更加小粒度的內存分割和映射方法,此時是否會想到Linux中的Buddy算法和slab內存分配機制呢,哈哈。另一種將虛擬地址轉換為物理地址的方法分頁機制應運而生了。

分頁機制

分頁機制就是把內存地址空間分為若干個很小的固定大小的頁,每一頁的大小由內存決定,就像Linux中ext文件系統將磁盤分成若干個Block一樣,這樣做是分別是為了提高內存和磁盤的利用率。試想以下,如果將磁盤空間分成N等份,每一份的大小(一個Block)是1M,如果我想存儲在磁盤上的文件是1K字節,那么其余的999字節是不是浪費了。所以需要更加細粒度的磁盤分割方式,可以將Block設置得小一點,這當然是根據所存放文件的大小來綜合考慮的,好像有點跑題了,我只是想說,內存中的分頁機制跟ext文件系統中的磁盤分割機制非常相似。

Linux中一般頁的大小是4KB,把進程的地址空間按頁分割,把常用的數據和代碼頁裝載到內存中,不常用的代碼和數據保存在磁盤中,還是以一個例子來說明,如下圖:


進程虛擬地址空間、物理地址空間和磁盤之間的頁映射關系

可以看到進程1和進程2的虛擬地址空間都被映射到了不連續的物理地址空間內(這個意義很大,如果有一天連續物理地址空間不夠,但是不連續的地址空間很多,如果沒有這種技術,程序就沒有辦法運行),甚至他們共用了一部分物理地址空間,這就是共享內存。

進程1的虛擬頁VP2和VP3被交換到了磁盤中,在程序需要這兩頁的時候,Linux內核會產生一個缺頁異常,然后異常管理程序會將其讀到內存中。

這就是分頁機制的原理,當然Linux中的分頁機制的實現還是比較復雜的,通過了也全局目錄,也上級目錄,頁中級目錄,頁表等幾級的分頁機制來實現的,但是基本的工作原理是不會變的。

分頁機制的實現需要硬件的實現,這個硬件名字叫做MMU(Memory Management Unit),他就是專門負責從虛擬地址到物理地址轉換的,也就是從虛擬頁找到物理頁。

轉載于:https://www.cnblogs.com/hello2mhb/articles/3359047.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273991.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273991.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

eclipse解決Android Library Project jar包重復導致的問題

Android Studio部分情況下用起來還是有些不適應的地方,用eclipse熟練了,在趕項目進度的情況下還得重拾eclipse。下面是今天碰到的一個老問題。 1.在導入Android Library工程文件的時候要把library一起拷貝到workspace中 2.在導入的Android Library工程文…

java中main函數的args參數

先說一下args的作用:我們習慣將一些有用的參數傳遞給我們定義的函數,那么可曾想過有參數傳遞給main函數?args就是傳遞給main函數的一個數組參數。可是main函數作為程序(application程序)的入口點,是由系統自動調用的,怎…

算法:排序算法的比較

默認為遞增順序&#xff1b;注&#xff1a;一下例子希望自己再次復習時&#xff0c;可以用筆在紙上畫畫內存圖。 包括有: 選擇排序冒泡排序插入排序 1.選擇排序 <--------------------------------------選擇排序---------------------------------------> 1、選擇排…

LTTng 簡介使用實戰

一、LTTng簡介 LTTng: (Linux Trace Toolkit Next Generation),它是用于跟蹤 Linux 內核、應用程序以及庫的系統軟件包。LTTng 主要由內核模塊和動態鏈接庫(用于應用程序和動態鏈接庫的跟蹤)組成。它由一個會話守護進程控制,該守護進程接受來自命令行接口的命令。babeltrace 項…

黑馬程序員-------------(十)Java基礎知識加強(一)

JDK1.5新特性 目錄1.之前已經學習過的JDK1.5新特性2.靜態導入 StaticImport3.可變參數 ...4.高級for循環5.枚舉6.泛型 Generic7.注解注&#xff1a;本章全部為重點內容。###################################################################################################…

java例子:數組 數3退1

500個人圍成一個圈子&#xff0c;數夠3人&#xff0c;就退出1個&#xff0c;問最后剩下的是幾號&#xff1f;檢驗先有5個人&#xff0c;應該留下第4個人&#xff0c;由于是數組&#xff0c;所以第四個人的下標是3. /*achieve the funtion :count 3 kids, the quit the third k…

Android版CCLabelTTF在setstring時出現黑塊

首先有個前提知識&#xff0c;cocos2dx里&#xff0c;只能在ui線程&#xff08;通常也就是主線程&#xff09;中進行渲染工作&#xff08;貌似現在有一些引擎是支持多線程渲染的&#xff0c;沒有深入研究&#xff09;&#xff0c;否則大約會因為多個線程同時給GPU發指令而出現問…

java例子:九九乘法表

來吧直接上代碼&#xff1a;public class Test{public static void main(String[] args) {for(int i 1; i<9;i){for (int j 1; j < i ;j ) {System.out.print(j"x"i""j*i" ");}System.out.print("\n");}} }運行之后&#xff1…

Apache的RewriteRule規則詳細介紹

R[code](force redirect) 強制外部重定向 (rkyW z強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.如果code不指定&#xff0c;將用缺省的302 HTTP狀態碼。 gN24M 3{CF(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。 m> 4ahue$G(force URL…

算法:查找

查找算法&#xff08;比較&#xff09;基本思想順序查找順序查找也稱為線形查找&#xff0c;屬于無序查找算法。從數據結構線形表的一端開始&#xff0c;順序掃描&#xff0c;依次將掃描到的結點關鍵字與給定值k相比較&#xff0c;若相等則表示查找成功&#xff1b;若掃描結束仍…

query上傳插件uploadify參數詳細分析

query上傳插件uploadify參數詳細分析 Uploadify Version 3.2 官網&#xff1a;http://www.uploadify.com/ 注&#xff1a;文件包里有兩個js分別是&#xff1a;jquery.uploadify.js 和 jquery.uploadify.min.js&#xff0c;兩者其實一樣&#xff0c;只需載入其中一個js即可。很明…

python 基礎 list和 tuple dict和set

list Python內置的一種數據類型是列表&#xff1a;list。list是一種有序的集合&#xff0c;可以隨時添加和刪除其中的元素。classmates [Michael, Bob, Tracy] 要刪除list末尾的元素&#xff0c;用pop()方法&#xff1a; 要刪除指定位置的元素&#xff0c;用pop(i)方法&#x…

IIS的安裝

xp上好像只能裝IIS5&#xff0c;IIS6根本就裝不了轉載于:https://www.cnblogs.com/hyk110988/p/3372592.html

py四種時間格式

time有四種類型&#xff08;time, datetime, string, timestamp&#xff09;1. time stringstring是最簡單的表示time的方式如如下代碼生成的即為string123>>> import time>>> time.ctime()Wed Nov 30 13:53:31 2016或者更簡單的生成一個字符串1time_string …

type_traits應用

工作遇到這樣的例子&#xff0c;對不同數據進行計算處理&#xff0c;得到一組結果集&#xff0c;包括計數、比例等。各個計算處理過程不同&#xff0c;結果集數據結構相同&#xff0c;但并非所有計算過程均有計數、比例的結果&#xff0c;有些可能只有計數&#xff0c;有些只有…

csv.writer寫入文件有多余的空行

在用csv.writer寫入文件的時候發現中間有多余的空行。 最早打開方式只是‘w’&#xff0c;會出現多余的空行&#xff0c;網上建議使用binary形式‘wb’打開可以解決問題&#xff1a; with open(egg2.csv, wb) as cf:12 不過只能在python2下運行&#xff0c;python3報錯&#xf…

java筆記之連接數據庫

1、一定不要忘了導入包 java工程&#xff1a;lib文件夾下mysql-connector-java.jar--->Build Path Web工程:當web下的servlet需要連接數據庫時&#xff0c;除了上一步導入包還要在WEB-INF/lib導入mysql-connector-java.jar 2、關于亂碼&#xff0c;查詢 在終端查詢數據時&am…

那些不能錯過的XCode插件

XCode顏色顯示插件ColorSense代碼里的那些冷冰冰的顏色數值&#xff0c;到底時什么顏色&#xff1f;如果你經常遇到這個問題&#xff0c;每每不得不運行下模擬器去看看&#xff0c;那么這個插件絕對不容錯過。更彪悍的是你甚至可以點擊顯示的顏色面板&#xff0c;直接通過系統的…

python爬蟲第一課 開發環境配置

一、Python3的安裝 二、請求庫的安裝 1、requests的安裝 直接pip安裝&#xff1a;pip3 install requests 2、Selenium的安裝 selenium是一個自動測試化工具&#xff0c;利用它我們可以驅動瀏覽器執行特定的動作&#xff0c;如點擊、下拉等操作。 直接pip安裝&#xff1a;pip in…

用JSLint精煉提升JavaScript代碼

由于移動應用的盛行和HTML5的廣泛運用&#xff0c;JavaScript正越來越流行。JavaScript受歡迎的部分原因是因為它的靈活便捷&#xff0c;你可以快速上手&#xff0c;它不需要重量級的開發環境&#xff0c;也不需要第三方應用支持&#xff0c;只要你打開一個文本編輯器&#xff…