小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

 taotao_2016 2019-08-17

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

比爾·蓋茨在上世紀(jì)80年代說的“640K ought to be enough for anyone”

也就是“640K內(nèi)存對哪個人來說都夠用了”

那個年代,微軟開發(fā)的還是DOS操作系統(tǒng),程序員們還在絞盡腦汁,想要用好這極為有限的640K內(nèi)存

而現(xiàn)在,我手頭的Mac Book Pro已經(jīng)是16G內(nèi)存了,上升了一萬倍還不止。

那比爾·蓋茨這句話在當(dāng)時也是完全的無稽之談么?有沒有哪怕一點(diǎn)點(diǎn)的道理呢?這一講里,我就和你一起來看一看。

1 程序裝載的挑戰(zhàn)

在運(yùn)行這些可執(zhí)行文件的時候,我們其實(shí)是通過一個裝載器,解析ELF或者PE格式的可執(zhí)行文件

裝載器會把對應(yīng)的指令和數(shù)據(jù)加載到內(nèi)存里面來,讓CPU去執(zhí)行。

裝載到內(nèi)存,裝載器需要滿足兩個要求

  • 可執(zhí)行程序加載后占用的內(nèi)存空間應(yīng)該是連續(xù)的
  • 執(zhí)行指令的時候,程序計數(shù)器是順序地一條一條指令執(zhí)行。這意味著,這一條條指令需要連續(xù)地存儲在一起
  • 需要同時加載很多個程序,并且不能讓程序自己規(guī)定在內(nèi)存中加載的位置
  • 雖然編譯出來的指令里已經(jīng)有了對應(yīng)的各種各樣的內(nèi)存地址,但是實(shí)際加載的時候,我們其實(shí)沒有辦法確保,這個程序一定加載在哪一段內(nèi)存地址上
  • 因?yàn)楝F(xiàn)在的計算機(jī)通常會同時運(yùn)行很多個程序,可能你想要的內(nèi)存地址已經(jīng)被其他加載了的程序占用

要滿足這兩個基本的要求,我們很容易想到一個辦法。那就是我們可以在內(nèi)存里面,找到一段連續(xù)的內(nèi)存空間,然后分配給裝載的程序,然后把這段連續(xù)的內(nèi)存空間地址,和整個程序指令里指定的內(nèi)存地址做一個映射。

指令里用到的內(nèi)存地址叫作虛擬內(nèi)存地址(Virtual Memory Address)

實(shí)際在內(nèi)存硬件里面的空間地址,我們叫物理內(nèi)存地址(Physical Memory Address)

程序里有指令和各種內(nèi)存地址,我們只需要關(guān)心虛擬內(nèi)存地址就行了

對于任何一個程序來說,它看到的都是同樣的內(nèi)存地址。我們維護(hù)一個虛擬內(nèi)存到物理內(nèi)存的映射表,這樣實(shí)際程序指令執(zhí)行的時候,會通過虛擬內(nèi)存地址,找到對應(yīng)的物理內(nèi)存地址,然后執(zhí)行。因?yàn)槭沁B續(xù)的內(nèi)存地址空間,所以我們只需要維護(hù)映射關(guān)系的起始地址和對應(yīng)的空間大小就可以了。

2 內(nèi)存分段

這種找出一段連續(xù)的物理內(nèi)存和虛擬內(nèi)存地址進(jìn)行映射的方法,我們叫分段(Segmentation)。

這里的段,就是指系統(tǒng)分配出來的那個連續(xù)的內(nèi)存空間。

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

分段的辦法很好,解決了程序本身不需要關(guān)心具體的物理內(nèi)存地址的問題,但它也有一些不足之處,第一個就是內(nèi)存碎片(Memory Fragmentation)

舉個例子

電腦有1GB的內(nèi)存

先啟動一個圖形渲染程序,占用了512MB的內(nèi)存

接著啟動一個Chrome瀏覽器,占用了128MB內(nèi)存

再啟動一個PY程序,占用了256MB內(nèi)存

這個時候,我們關(guān)掉Chrome,于是空閑內(nèi)存還有1024 - 512 - 256 = 256MB

按理來說,我們有足夠的空間再去裝載一個200MB的程序。但是,這256MB的內(nèi)存空間不是連續(xù)的,而是被分成了兩段128MB的內(nèi)存

因此,實(shí)際情況是,我們的程序沒辦法加載進(jìn)來。

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

當(dāng)然了,有辦法解決 --- 內(nèi)存交換(Memory Swapping)

我們可以把Python程序占用的256MB內(nèi)存寫到硬盤,再從硬盤上讀回來到內(nèi)存里面

不過讀回來的時候,我們不再把它加載到原來的位置,而是緊緊跟在那已經(jīng)被占用了的512MB內(nèi)存后面

這樣,我們就有了連續(xù)的256MB內(nèi)存空間,就可以去加載一個新的200MB的程序。如果你自己安裝過Linux操作系統(tǒng),你應(yīng)該遇到過分配一個swap硬盤分區(qū)的問題

這塊分出來的磁盤空間,其實(shí)就是專門給Linux操作系統(tǒng)進(jìn)行內(nèi)存交換用的。

虛擬內(nèi)存、分段,再加上內(nèi)存交換

看起來似乎已經(jīng)解決了計算機(jī)同時裝載運(yùn)行很多個程序的問題

不過三者的組合仍然會遇到一個性能瓶頸

  • 硬盤的訪問速度要比內(nèi)存慢很多
  • 而每一次內(nèi)存交換,我們都需要把一大段連續(xù)的內(nèi)存數(shù)據(jù)寫到硬盤上

所以,如果內(nèi)存交換的時候,交換的是一個很占內(nèi)存空間的程序,這樣整個機(jī)器都會顯得卡頓。

3 內(nèi)存分頁

既然問題出在內(nèi)存碎片和內(nèi)存交換的空間太大上,那么解決問題的辦法就是,少出現(xiàn)一些內(nèi)存碎片。

另外,當(dāng)需要進(jìn)行內(nèi)存交換的時候,讓需要交換寫入或者從磁盤裝載的數(shù)據(jù)更少一點(diǎn),這樣就可以解決這個問題。

這個辦法,在現(xiàn)在計算機(jī)的內(nèi)存管理里面,就叫作內(nèi)存分頁(Paging)

**和分段這樣分配一整段連續(xù)的空間給到程序相比

分頁則是把整個物理內(nèi)存空間切成一段段固定尺寸的大小**

而對應(yīng)的程序所需要占用的虛擬內(nèi)存空間,也會同樣切成一段段固定尺寸的大小。

這樣一個連續(xù)并且尺寸固定的內(nèi)存空間,我們叫頁(Page)

從虛擬內(nèi)存到物理內(nèi)存的映射,不再是拿整段連續(xù)的內(nèi)存的物理地址,而是按照一個個頁來的。

頁的尺寸一般遠(yuǎn)遠(yuǎn)小于整個程序的大小。

在Linux下,我們通常只設(shè)置成4KB。你可以通過命令看看你手頭的Linux系統(tǒng)設(shè)置的頁的大小。

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

由于內(nèi)存空間都是預(yù)先劃分好的,也就沒有不能使用的碎片,而只有被釋放出來的很多4KB的頁。

即使內(nèi)存空間不夠,需要讓現(xiàn)有的、正在運(yùn)行的其他程序

通過內(nèi)存交換釋放出一些內(nèi)存的頁出來,一次性寫入磁盤的也只有少數(shù)的一個頁或者幾個頁,不會花太多時間,讓整個機(jī)器被內(nèi)存交換的過程給卡住。

重學(xué)計算機(jī)組成原理(八)- 程序的裝載

分頁的方式使得加載程序的時候,不再需要一次性把程序加載到物理內(nèi)存中

可以在進(jìn)行虛擬內(nèi)存和物理內(nèi)存的頁之間的映射后,并不真的把頁加載到物理內(nèi)存里,而是只在程序運(yùn)行中,需要用到對應(yīng)虛擬內(nèi)存頁里面的指令和數(shù)據(jù)時,再加載到物理內(nèi)存里面去。

實(shí)際上,我們的操作系統(tǒng),的確是這么做的

當(dāng)要讀取特定的頁,卻發(fā)現(xiàn)數(shù)據(jù)并沒有加載到物理內(nèi)存里的時候,就會觸發(fā)一個來自于CPU的缺頁錯誤(Page Fault)

操作系統(tǒng)會捕捉到這個錯誤,然后將對應(yīng)的頁,從存放在硬盤上的虛擬內(nèi)存里讀取出來,加載到物理內(nèi)存里。這種方式,使得我們可以運(yùn)行那些遠(yuǎn)大于我們實(shí)際物理內(nèi)存的程序。同時,這樣一來,任何程序都不需要一次性加載完所有指令和數(shù)據(jù),只需要加載當(dāng)前需要用到就行了。

通過虛擬內(nèi)存、內(nèi)存交換和內(nèi)存分頁這三個技術(shù)的組合,我們最終得到了一個讓程序不需要考慮實(shí)際的物理內(nèi)存地址、大小和當(dāng)前分配空間的解決方案。

這些技術(shù)和方法,對于我們程序的編寫、編譯和鏈接過程都是透明的。這也是我們在計算機(jī)的軟硬件開發(fā)中常用的一種方法,就是加入一個間接層。

通過引入虛擬內(nèi)存、頁映射和內(nèi)存交換,我們的程序本身,就不再需要考慮對應(yīng)的真實(shí)的內(nèi)存地址、程序加載、內(nèi)存管理等問題了。任何一個程序,都只需要把內(nèi)存當(dāng)成是一塊完整而連續(xù)的空間來直接使用。

4 總結(jié)

電腦只要640K內(nèi)存就夠了嗎?很顯然,現(xiàn)在來看,比爾·蓋茨的這個判斷是不合理的,那為什么他會這么認(rèn)為呢?因?yàn)樗彩且粋€很優(yōu)秀的程序員??!

在虛擬內(nèi)存、內(nèi)存交換和內(nèi)存分頁這三者結(jié)合之下,你會發(fā)現(xiàn),其實(shí)要運(yùn)行一個程序,“必需”的內(nèi)存是很少的。CPU只需要執(zhí)行當(dāng)前的指令,極限情況下,內(nèi)存也只需要加載一頁就好了。再大的程序,也可以分成一頁。每次,只在需要用到對應(yīng)的數(shù)據(jù)和指令的時候,從硬盤上交換到內(nèi)存里面來就好了。以我們現(xiàn)在4K內(nèi)存一頁的大小,640K內(nèi)存也能放下足足160頁呢,也無怪乎在比爾·蓋茨會說出“640K ought to be enough for anyone”這樣的話。

不過呢,硬盤的訪問速度比內(nèi)存慢很多,所以我們現(xiàn)在的計算機(jī),沒有個幾G的內(nèi)存都不好意思和人打招呼。

那么,除了程序分頁裝載這種方式之外,我們還有其他優(yōu)化內(nèi)存使用的方式么?下一講,我們就一起來看看“動態(tài)裝載”,學(xué)習(xí)一下讓兩個不同的應(yīng)用程序,共用一個共享程序庫的辦法。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多