操作系統--虛擬內存

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"一.前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在之前研究進程上下文切換和golang內存分配器的過程中,發現虛擬內存在其中都扮演着十分重要的角色,之前有學習和了解過虛擬內存,但是隨着時間推移也只知道一個概念,現在想要帶着問題去再學習一遍虛擬內存,希望這篇文章也能幫助你們更好的理解虛擬內存。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.進程初始化的時候是如何分配的內存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.虛擬內存的具體工作流程","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"二.詳細介紹","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.1 簡介","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"虛擬內存是一個抽象概念,它爲每個進程提供了一個假象,即每個進程都在獨佔的使用主存。每個進程看到的內存都是一致的,稱爲「","attrs":{}},{"type":"text","marks":[{"type":"bgcolor","attrs":{"color":"#ffffff","name":"user"}}],"text":"虛擬地址空間」","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"虛擬內存主要提供了","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"三個能力","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它將主存看做是一個存儲在磁盤上的地址空間的高速緩存,在主存中只保存活動區域,並根據需要在磁盤和主存之間來回傳送數據,通過這種方式高效使用了主存","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它爲每個進程提供了一致的地址空間,簡化了內存管理","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它保護了每個進程的地址空間不被其他進程破壞","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.2 如何工作","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fa/fa83b9fc3be8370acf7eeb6e09dcd253.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如圖所示,cpu通過生產一個虛擬地址4001訪問主存,虛擬地址再mmu的轉換下映射爲物理地址中的2,通過講翻譯後的物理地址傳給主存,主存讀取從物理地址2開始的4個字節將其返回給cpu。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.3 名詞解釋","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"知道了大概的處理流程,接下來講解一下虛擬內存相關的幾個名詞。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.1 地址空間","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個非負整數地址的有序集合,在帶有虛擬內存的系統中,cpu從一個有N=2^n個地址的地址空間中生成虛擬地址,這個地址空間成爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"虛擬地址空間","attrs":{}},{"type":"text","text":",要求是2的冪,一般由計算機的位數決定,如32位對應2^32,64對應2^64。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"物理地址空間","attrs":{}},{"type":"text","text":"則對應的是系統中物理內存的M個字節,沒有2的冪的要求 ","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.3.1 頁表","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"頁表將虛擬頁映射到物理頁","attrs":{}},{"type":"text","text":",每次地址翻譯硬件將一個虛擬地址轉換爲物理地址時,都會讀取頁表,操作系統負責維護頁表內容,以及在磁盤與DRAM(Dynamic Random Access Memory)之間來回傳送頁。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cb/cb51aea6a413ff78a5dd3fbe210e2747.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"頁面分配的三種情況","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頁表是一個頁表條目(pte:page table entry)的數組,每一條由一個有效位和一個n位地址字段組成,有效位表明了該虛擬頁是否被緩存在DRAM,如果有效,那麼地址字段就表明了DRAM中的物理頁起始地址。圖中vp1,vp2,vp4都是這種情況。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"若是空地址,則表明這個虛擬頁還沒有被分配,vp0就是這種情況。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"若是有地址,但是有效位爲0,那麼就表明虛擬頁被分配在了磁盤上,地址指向的就是虛擬頁在磁盤的起始地址。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"缺頁","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"DRAM緩存不被命中就叫做缺頁。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我們去訪問vp3,就會發現vp3不在DRAM中,由於磁盤和DRAM的訪問速度差了100000多倍,那麼我們就需要將vp3緩存到DRAM中,此時我們將vp3從磁盤複製到物理內存(如果此時物理內存不夠,就按照一定的算法將原本保存在裏面的頁面移出,並設置頁表中對應的標記位爲無效),再將vp3在頁表中對應的pte有效位設置爲有效,修改地址從磁盤指向DRAM。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"進程頁表","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"虛擬內存爲每個進程提供了一個獨立頁表,因而是一個獨立的虛擬地址空間,一來方便用戶操作,二來方便用戶共享內存,因爲不同的頁表支持映射到同一個共享物理頁面上。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.4 地址翻譯","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.4.1 名詞介紹","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"頁表基址寄存器","attrs":{}},{"type":"text","text":"(page table base register PTBR):在cpu寄存器中指向當前頁表(進程上下文切換中要更換)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"n位虛擬地址","attrs":{}},{"type":"text","text":":包含一個p位的虛擬頁面偏移(virtual Page Offset,VPO)和一個n-p位的虛擬頁號(virtual","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" page number,VPN),MMU利用VPN來選擇適合的pte。物理頁面的偏移量則與虛擬頁面一致。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"MMU","attrs":{}},{"type":"text","text":"(Memory Management Unit,內存管理單元):用於翻譯虛擬地址和物理地址映射關係","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.4.2 地址翻譯整體流程","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/65/65c9ae817006c39013423a1c46ee47f9.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"cpu生成虛擬地址,傳遞給MMU","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"mmu生成pte地址(這一步是mmu通過虛擬地址的虛擬頁號獲取的),並從高速緩存/主存得到它","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"高速緩存/主存將pte返回給mmu","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"mmu通過頁表,構造物理地址,將其傳給高速緩存/主存","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"高速緩存/主存將請求的數據字給處理器","attrs":{}}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.4.3 TLB","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由上面的知識,每次獲取內存mmu都需要去內存取一次pte,利用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"緩存思想(設計系統或者提高請求效率的時候都可以往這個上面靠,最基本原理就是空間換取時間)","attrs":{}},{"type":"text","text":",操作系統發明了tlb(translation lookaside buffer),他是一個關於pte的小緩存(注意進程上下文切換也需要清空tlb)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了tlb,如果發生命中,那麼過程如下。","attrs":{}}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"cpu生成虛擬地址,傳遞給MMU","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"mmu從tlb取出相應的pte","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"mmu將虛擬地址翻譯成一個物理地址,並將它發送到高速緩存/貯存","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"高速緩存/主存將請求的數據字給處理器","attrs":{}}]}]}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"三.問題思考","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"經過書本的系統學習,我已經瞭解了虛擬內存的工作原理,解決了問題二,還有進程初始化的時候是如何分配的內存這一問題。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以linux爲例子,先看看在linux系統下進程的虛擬內存結構","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cb/cb3a454275819c0851dc0a9caac2706c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"進程能獲取多少內存主要取決於運行時堆的內存分配,其餘的內存消耗都是每個進程必要的,也就是說一個沒有跑起來的進程消耗的內存都在物理內存上,等進程跑起來,會由操作系統對進程申請的內存進行動態分配,決定哪些放在物理內存,哪些放在主存,這是我們所不需要感知的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"四.參考文檔","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"深入理解計算機系統","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.guru99.com/stack-vs-heap.html","title":"","type":null},"content":[{"type":"text","text":"https://www.guru99.com/stack-vs-heap.html","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章