<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    內(nèi)存管理兩部曲之虛擬內(nèi)存管理

    共 3548字,需瀏覽 8分鐘

     ·

    2021-06-01 08:40

    傳統(tǒng)存儲管理存在的問題

    虛擬內(nèi)存這個東西他為什么會出現(xiàn)?他出現(xiàn)的背景是什么?

    前文 內(nèi)存管理兩部曲之物理內(nèi)存管理 提到:隨著用戶程序功能的增加,進程所需要的內(nèi)存空間越來越大,進程空間很容易就突破了物理內(nèi)存的實際大小,導致進程無法運行。

    因此,為了解決內(nèi)存不足的情況,緩和大程序與小內(nèi)存之間的矛盾,擴充內(nèi)存容量勢在必行。

    可以從物理和邏輯兩方面來考慮擴充內(nèi)存容量,物理擴容沒啥技術含量,需要我們研究的自然是如何從邏輯上擴充內(nèi)存容量。

    所謂邏輯擴充,就是說實際上物理內(nèi)存的容量沒有發(fā)生改變,但是它能裝的東西卻變多了,使得用戶看來似乎有一個比實際內(nèi)存大得多的內(nèi)存。

    對內(nèi)存的邏輯擴充技術主要有三種:覆蓋技術、交換技術、以及虛擬內(nèi)存(Virtual Memory),也稱為虛擬存儲器。事實上,這些邏輯擴充技術的核心理念都是一致的,研究的都是將哪個進程(或進程的某部分)暫時從內(nèi)存移到外存(磁盤),以騰出內(nèi)存空間供其他進程(或進程的某部分)占用。

    覆蓋(Overlay)和交換(Swapping)這兩種存在于早期操作系統(tǒng)中的邏輯擴充技術現(xiàn)在已經(jīng)成為歷史,這里就簡單介紹下:

    前文說過,早期操作系統(tǒng)僅將內(nèi)存空間分成兩塊:系統(tǒng)區(qū)(用于存放操作系統(tǒng)相關數(shù)據(jù))和用戶區(qū)(用于存放用戶進程相關數(shù)據(jù),內(nèi)存中只能有一道用戶程序,用戶程序獨占整個用戶區(qū)空間,顯然,內(nèi)存空間容不下某個用戶程序的現(xiàn)象常會發(fā)生。

    覆蓋技術(Overlay)的基本思想就是:程序運行時并非任何時候都要訪問程序及數(shù)據(jù)的所有部分(尤其是大程序),因此可以把用戶空間(內(nèi)存)分成一個固定區(qū)和一個或多個覆蓋區(qū)。

    將程序經(jīng)常活躍的部分放在固定區(qū),其余部分按調(diào)用關系進行分段:首先將那些即將要用的段放在覆蓋區(qū),其他段放在外存(磁盤),在需要調(diào)用前由用戶來安排特定的系統(tǒng)調(diào)用將這些放在外存中的段調(diào)入覆蓋區(qū),替換覆蓋區(qū)中原有的段。

    覆蓋技術的缺點顯而易見并且可以說是讓人無法接受的,那就是覆蓋技術是把解決內(nèi)存空間不足的問題交給了用戶。操作系統(tǒng)僅僅為用戶提供將覆蓋段調(diào)入內(nèi)存的系統(tǒng)調(diào)用,但是必須由用戶自己來說明覆蓋哪個段、調(diào)入哪個段。

    合著我用個電腦還得算著怎么才能讓我的程序不崩潰?

    OK,可以看出來,覆蓋技術其實是用在同一個作業(yè)/進程的不同段之間的,那么不同的作業(yè)/進程之間怎么辦呢?

    這就是交換技術的適用場景。

    交換技術(Swapping)的基本思想是:空閑進程/作業(yè)主要存儲在外存(磁盤)上,當其中某個進程/作業(yè)需要運行的時候,就將其從磁盤中完整地調(diào)入內(nèi)存,使該進程運行一段時間,然后再把它返回磁盤。所以說當進程/作業(yè)不運行的時候它們是不會占用內(nèi)存的。


    事實上,覆蓋和交換技術分別解決了傳統(tǒng)存儲管理(物理內(nèi)存管理)中存在的某個問題:

    • 覆蓋技術打破了作業(yè)/進程必須一次性全部裝入內(nèi)存后才能開始運行(一次性)的限制
    • 交換技術打破了一旦作業(yè)被裝入內(nèi)存,就會一直駐留在內(nèi)存中,直至作業(yè)運行結束(駐留性)的限制

    當然了,Anyway,這兩種邏輯擴充技術已經(jīng)成為歷史,虛擬內(nèi)存技術才是目前的主流,它綜合了這兩種古老技術的特點,單槍匹馬解決了傳統(tǒng)存儲管理中存在的這兩個問題。

    什么是虛擬內(nèi)存

    有了上述交換技術的鋪墊,理解起虛擬內(nèi)存來也就不那么陌生了。

    當然了,在此之前,我一定要著重聲明的是,不要把虛擬內(nèi)存當作一個實際存在的東西,它是一門技術!和交換技術覆蓋技術一樣是一門用來邏輯擴充內(nèi)存空間的技術!

    虛擬內(nèi)存技術基于一個非常重要的原理,局部性原理

    1)時間局部性:如果執(zhí)行了程序中的某條指令,那么不久后這條指令很有可能再次執(zhí)行;如果某個數(shù)據(jù)被訪問過,不久之后該數(shù)據(jù)很可能再次被訪問。(因為程序中存在大量的循環(huán))

    2)空間局部性:一旦程序訪問了某個存儲單元,在不久之后,其附近的存儲單元也很有可能被訪問(因為很多數(shù)據(jù)在內(nèi)存中都是連續(xù)存放的,并且程序的指令也是順序地在內(nèi)存中存放的)

    基于這個局部性原理,在一個程序裝入內(nèi)存的時候,可以只將這個程序中很快會用到的部分裝入內(nèi)存,暫時用不到的部分仍然留在外存(磁盤),并且程序可以正常執(zhí)行;

    而在程序執(zhí)行過程中,當 CPU 所需要的信息不在內(nèi)存中的時候,由操作系統(tǒng)負責將所需信息從外存(磁盤)調(diào)入內(nèi)存,然后繼續(xù)執(zhí)行程序;

    如果調(diào)入內(nèi)存的時候內(nèi)存空間不夠,由操作系統(tǒng)負責將內(nèi)存中暫時用不到的信息換出到外存。

    以上,就是虛擬內(nèi)存技術。

    如何實現(xiàn)虛擬內(nèi)存技術

    可以看見,虛擬內(nèi)存允許一個作業(yè)/進程分多次調(diào)入內(nèi)存,那如果采用連續(xù)分配方式,不方便實現(xiàn),所以虛擬內(nèi)存技術的實現(xiàn)是建立在不連續(xù)分配管理方式之上的。

    傳統(tǒng)的基本分頁管理、基本分段管理、基本段頁式管理和虛擬內(nèi)存技術結合,分別稱為請求分頁管理(頁式虛存系統(tǒng))、請求分段管理(段式虛存系統(tǒng))、請求段頁式管理(段頁式虛存系統(tǒng))。

    這幾個概念非常容易混淆,其實很容易區(qū)分,記住這句話就 OK,摘自百度百科:

    如果不具備請求調(diào)頁、頁面置換的功能,則稱為基本分頁管理(或稱為純分頁管理),它不具有支持實現(xiàn)虛擬內(nèi)存的功能,它要求把每個作業(yè)(進程)全部裝入內(nèi)存后方能運行。

    請求分段存儲管理也差不多,它建立在分段存儲管理之上,但增加了請求調(diào)段、段置換功能。

    請求調(diào)頁、頁面置換 和 請求調(diào)段、段置換概念差不多,這里以請求調(diào)頁和頁面置換為例解釋下。

    • 在程序執(zhí)行過程中,當所訪問的信息不在內(nèi)存時,由操作系統(tǒng)負責將所需信息從外存(磁盤)調(diào)入內(nèi)存,然后繼續(xù)執(zhí)行程序(操作系統(tǒng)要提供請求調(diào)頁的功能, 將內(nèi)存中缺失的頁面從磁盤調(diào)入內(nèi)存 );
    • 若內(nèi)存空間不夠,由操作系統(tǒng)負責將內(nèi)存中暫時用不到的信息換出到磁盤(操作系統(tǒng)要提供頁面置換的功能, 將暫時用不到的頁面換出磁盤)。

    具體來說,在頁式虛存系統(tǒng)中,每當 CPU 要訪問的頁面不在內(nèi)存時,就會產(chǎn)生一個缺頁中斷,然后由操作系統(tǒng)的缺頁中斷處理程序來處理中斷。此時,缺頁的這個進程/作業(yè)就會被阻塞住,放入阻塞隊列,調(diào)頁完成后再將其喚醒,放回就緒隊列。

    • 如果內(nèi)存中有空閑塊,則為該進程分配一個空閑塊,將所缺的頁面裝入這個塊中,并修改頁表中相應的頁表項。
    • 如果內(nèi)存中沒有空閑塊,則由頁面置換算法選擇一個頁面淘汰,若該頁面在內(nèi)存期間被修改過,則要將其寫回外存,未修改過的頁面不用寫回外存。

    可以看出來,這并不是一個簡單的過程,基本分頁管理中的簡單頁表已經(jīng)無法勝任這樣的工作。

    我們還是先來回顧下基本分頁管理的頁表,它只有頁號和塊號兩個字段:

    請求分頁管理的頁表自然是會復雜不少的:

    1)為了實現(xiàn) “請求調(diào)頁” 功能,操作系統(tǒng)需要知道每個頁面是否已經(jīng)調(diào)入內(nèi)存,如果還沒調(diào)入,那么也需要知道該頁面在磁盤中存放的位置。

    2)而當內(nèi)存空間不夠時,要實現(xiàn) “頁面置換” 功能,操作系統(tǒng)需要通過某些指標來決定到底換出哪個頁面,有的頁面沒有被修改過,就不用浪費時間寫回磁盤;有的頁面修改過,就需要將磁盤中的舊數(shù)據(jù)覆蓋。因此,操作系統(tǒng)也需要記錄各個頁面是否被修改的信息。

    為此,請求分頁管理的頁表中添加了 4 個字段:

    • 狀態(tài)位:該頁面是否已調(diào)入內(nèi)存
    • 訪問字段:可記錄該頁面最近被訪問過幾次,或記錄上次訪問該頁面的時間,供頁面置換算法換出頁面時參考
    • 修改位:該頁面調(diào)入內(nèi)存后是否被修改過
    • 外存地址:該頁面在外存中的存放地址

    頁面置換算法也是一個很重要的內(nèi)容,本來應該在這篇文章里一起寫的,But 想到 “頁面置換” 問題不僅僅是在虛擬內(nèi)存中存在,在計算機設計的其他領域也會同樣發(fā)生(比如多數(shù)計算機都會把最近使用過的 32 字節(jié)或者 64 字節(jié)存儲塊保存在一個或多個高速緩存中,當這些高速緩存存滿后就必須選取一些塊丟棄掉,以此來存入最新的使用過的存儲塊),所以決定后續(xù)單開一篇文章。




    • 博主小碩在讀,深耕 Java,目前在維護一個教程類倉庫 CS-Wiki「Gitee 官方推薦項目,現(xiàn)已 1.7k+ star,倉庫地址:https://gitee.com/veal98/CS-Wiki」,公眾號上的文章也會在此同步更新,歡迎各位前來交流學習。
    • 準備春招秋招的小伙伴可以參考我的這個論壇項目 Echo「Gitee 官方推薦項目,現(xiàn)已 800+ star,倉庫地址:https://gitee.com/veal98/Echo」。配套教程正在同步更新中,公眾號后臺回復 "Echo" 即可免費獲取。
    • 另外,雖然現(xiàn)在本號仍然很小,不過我還是建了一個交流群『小牛肉和它的小伙伴們』,感興趣的各位可以下方掃碼加我微信回復 "進群",我拉你進群:

    瀏覽 67
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    日本色情视频在线观看 | 人人操91| 亚洲每日在线 | 日逼网站入口 | 人人肏屄|