紅客突擊隊
虛擬內存前言繼續閱讀《深入理解計算機系統》這本經典書籍
本節是第九章
虛擬內存
虛擬內存為每個進程提供一個大的、一致的、私有的地址空間
將主存看成一個存儲在磁碟上的地址空間的高速緩存
為每個進程提供一致的地址空間
保護每個進程的地址空間不被其他進程破壞
1、物理和虛擬尋址物理尋址是CPU訪問內存最自然的方式
現在都是用虛擬尋址
內存管理單元(MMU)利用存放在主存中的查詢表動態翻譯虛擬地址
主要有以下幾點考慮
地址空間:非負整數地址的有序集合
線性地址空間:整數連續
虛擬地址空間:CPU從一個N=2^n個地址的地址空間中生成虛擬地址
物理地址空間:對應物理內存的M個字節
虛擬內存就是存儲在磁碟上的 N 個連續字節的數組
這個數組的部分內容,會緩存在 DRAM 中
在 DRAM 中的每個緩存塊(cache block)就稱為頁(page)
類似緩存,我們需要儘可能從DRAM讀取數據:
更大的頁尺寸(page size):通常是 4KB,有的時候可以達到 4MB
全相聯(Fully associative):每一個虛擬頁(virual page)可以放在任意的物理頁(physical page)中,沒有限制。
映射函數非常複雜,所以沒有辦法用硬體實現,通常使用 Write-back 而非 Write-through 機制
做法:頁表
那查詢時
看起來效率似乎不高
但局部性原則使得程序趨向於在一個較小的活動頁面集合上工作
如前所說
每個進程都有自己的虛擬地址空間
映射如下
一個好處是
如果兩個進程間有共享的數據,那麼直接指向同一個物理頁即可
且有以下幾點
頁表中的每個條目的高位部分是表示權限的位
MMU 可以通過檢查這些位來進行權限控制(讀、寫、執行)
一些符號
一個例子
通過虛擬地址找到頁表(page table)中對應的條目
檢查有效位(valid bit),是否需要觸發頁錯誤(page fault)
然後根據頁表中的物理頁編號(physical page number)找到內存中的對應地址
最後把虛擬頁偏移(virtual page offset)和前面的實際地址拼起來,就是最終的物理地址了
如果是命中
如果是缺頁
想要更快
直接在 MMU 進行一部分的工作
有了Translation Lookaside Buffer(TLB)
VPN + VPO 就是虛擬地址
分成三部分,分別用於匹配標籤、確定集合
如果 TLB 中有對應的記錄,那麼直接返回對應頁表項(PTE)即可
如果沒有的話,就要從緩存/內存中獲取,並更新 TLB 的對應集合
多級頁表
因為往往虛擬地址的位數比物理內存的位數要大得多
所以保存頁表項(PTE) 所需要的空間也是一個問題
故採用多級頁表
動態內存分配器會管理一個虛擬內存區域,稱為堆(heap)
分配器以塊為單位來維護堆,可以進行分配或釋放
有兩種類型的分配器:
關於malloc和free的調用
分配器有以下限制
在這些約束下,分配器試圖實現吞吐率最大化和內存使用率最大化
造成堆利用率低的主要原因是碎片 of course
垃圾收集器
一種動態內存分配器
自動釋放程序不再需要的已分配塊
將內存視為一張有向可達圖,釋放不可達節點
9、內存相關錯誤1、間接引用壞指針
一個例子如下
錯誤的寫為
2、讀未初始化的內存
3、允許棧緩衝區溢出
必須用fgets函數限制輸入串的大小
4、假設指針和他們指向的對象大小相同
5、錯位錯誤
6、引用指針而不是它所指的對象
7、誤解指針運算
8、引用不存在的變量
9、引用空閒堆塊中的數據
10、內存洩漏
主要了解虛擬內存是怎麼一回事兒
它的一些功能與作用
略過了動態內存分配的一些詳細操作