日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

闲聊Linux内存管理(1)

發布時間:2025/3/15 linux 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闲聊Linux内存管理(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天還有時間,之前一直想抽時間來寫寫Linux內核原理相關的東西,關注點不在代碼,而在于內在的原理和機制,讓大家對Linux內核有個總體的感性認識,個人認為這很有必要,把看似復雜、深不可測的內核實現,用大家都能理解的方式,用講故事的方式,講給大家聽,如果有人聽后,有原來不過如此的感覺,那我的目的就達到了。

# 內存管理

從哪里開始呢?還是從最基礎的內存管理開始吧。

內存管理是Linux內核中最基礎,也是相當重要的部分。理解相關原理,不管是對內存的理解,還是對大家寫用戶態代碼都很有幫助。很多書上、很多文章都寫了相關內容,但個人總覺得內容太復雜,不是太容易理解,這里想用我自己理解的簡單的方式來描述,希望能有所幫助,按自己的思路,可能有點亂,見諒。

從內存分配開始

大家寫代碼時,應該都會分配內存,不同語言,層次不同,使用的接口不同,不管使用哪種方式,在Linux系統中,基本上都會調用到C庫的malloc接口,那就從malloc分配內存開始。

malloc就是用于分配一段內存,但這里分配到的內存并非物理內存,而是虛擬內存,這里沒有嚴格區分虛擬地址、線性地址之類的概念,只會給大家添負擔,也不深入講述物理內存和虛擬內存的概念,書上通常有大量的篇幅介紹,大家可以簡單這樣理解:

  • 虛擬內存就是從進程的角度看,邏輯上的概念,并不實際存在;

  • 物理內存就對應物理上內存條上的內存;

  • 虛擬內存和物理內存有對應關系;
  • 虛擬內存分配時,相應的物理內存還沒有分配;

既然虛擬內存并不實際存在,那么分配來有何用處呢,如果要向其中寫數據,數據如何寫入呢?會寫到哪里去呢?

當然,內存分配后就是拿來用的,如果不能用(比如寫數據),那就沒有意義了。前面說的虛擬內存和物理內存有對應關系,當分配虛擬內存時,相應的物理內存還沒有分配,這里有幾個關鍵問題:

  • 虛擬內存和物理內存的對應關系由誰來負責維護,如何對應?
  • 物理內存何時分配?
  • 虛擬內存到物理內存的映射

    先來解答問題1。

    頁表來建立虛擬內存到物理內存之間的映射關系。?頁表是啥?

    簡單看,頁表就是在內存中的一張表(不詳細介紹頁表的具體格式啥的,看書就可以了),可以簡單看做一張hash表,記錄的是虛擬地址和物理地址的對應關系,每個虛擬地址對應一個表項,通過這張表,就能將虛擬地址轉換為物理地址,也就能建立虛擬內存到物理內存的映射關系了。

    誰用頁表?

    頁表有了,那誰來用呢?不可能是應用程序自己用吧,我寫代碼時好像從來都沒見過頁表

    當然,用戶看到的只是虛擬地址(虛擬內存),其他的對用戶都是透明的~

    CPU中有個硬件單元,叫MMU(內存管理單元),頁表就是給MMU硬件用的,MMU使用頁表進行虛擬地址到物理地址的映射。也就是說,地址映射是由硬件完成的,軟件(包括操作系統內核自身)都不管關心。

    都說軟件不用關心了,那我們為嘛還需要講頁表?

    軟件只是不用頁表而且,但頁表的創建和維護都是由軟件(操作系統內核)負責的,也就是說我們(軟件)創建虛擬內存和物理內存的映射關系,然后由硬件來自動進行地址映射(轉換),我們不需要關心具體的轉換過程。

    前面說了,頁表是在內存中,而頁表是由軟件創建的,那MMU如果知道頁表到底在哪兒呢?

    簡單說,需要我們(軟件)告訴它在哪兒,如何告訴?當然,寫寄存器。CPU上有特別的寄存器(CR3),向其中寫入頁表的地址,MMU就知道了,然后硬件自己使用即可,我們就不管了。

    有多少張頁表?

    看似一張頁表就能完成所有的地址映射了?

    當然不行,如果是這樣,虛擬內存就沒有什么必要存在了。

    這里又涉及新概念了:進程,這是操作系統中最基礎的概念,其實不“新”。

    系統中,所有任務都是以進程方式運行的,每個進程都有自己的獨立的虛擬地址空間,好像又說復雜了,簡單說,就是每個進程都有自己的虛擬內存,獨立代表,其他進程看不到自己的虛擬內存,那么就意味著,每個進程都需要獨立的虛擬內存到物理內存的映射,就是說,每個進程都需要自己的頁表

    所以,系統中有多少進程,就有多少張頁表。

    頁表創建

    前面說了,頁表的創建和維護是由操作系統內核完成的,那何時創建頁表呢?

    如前面所說,每個進程都需要自己的頁表,顯然,頁表需要在進程創建時建立。具體的創建過程和原理就不講了。

    頁表的維護

    如果維護頁表?

    當然,進程自己維護,如果維護?

    拿前面的例子說,malloc分配虛擬內存后,并沒有分配物理內存,也沒有建立映射關系,沒有修改頁表,那到底什么時候,由誰來做映射?

    答案是:“缺頁異常”。

    缺頁異常

    缺頁異常(page fault)又是另一個專業術語,表面上看好像不好理解。

    簡單看,就是一個異常。什么是異常?這又是硬件上的概念了,具體看看書

    簡單說,就是硬件上的一種機制,當硬件檢測到某種“不對”時,主動觸發,然后會自動跳轉到異常處理程序處理。異常跟中斷類似,區別在于,中斷是異步的,由外設觸發;異常是同步的,由CPU自己觸發;好像又扯遠了。

    缺頁異常就是一種特定的異常,觸發條件是:MMU檢測到頁表項(頁表中的項~)不存在。

    何時觸發缺頁異常?

    MMU何時會去檢測頁表項?

    當CPU需要訪問某個虛擬地址時,比如向某個虛擬地址寫數據(memset),需要將虛擬地址轉換成物理地址,此時MMU就會自動去頁表中找相應的頁表項,如果發現此時相應的頁表項(也就是虛擬地址到物理地址的映射關系)還不存在,那么就會自動從硬件層面觸發缺頁異常。

    也就說,缺頁異常是硬件自己觸發的,條件是當需要訪問某個虛擬地址,而該虛擬地址還沒有相應的頁表項時。

    典型的場景就是,當malloc之后,對相應的虛擬地址執行memset操作。

    缺頁異常中干嘛?

    缺頁異常后,會跳轉到相應的異常處理程序處理,該異常處理程序是內核中提前注冊好的,其中要做的主要操作,就是:分配物理內存,然后修改相應進程的頁表,建立該物理內存和虛擬內存的映射關系(頁表項)。

    當然,實際實現要復雜得多,這里不詳細描述。

    回頭看看

    再來重頭捋一下內存分配過程:

  • 用戶態程序使用malloc接口,分配虛擬地址。
  • 用戶程序訪問該虛擬地址,比如memset。
  • 硬件(MMU)需要將虛擬地址轉換為物理地址。
  • 硬件讀取頁表。
  • 硬件發現相應的頁表項不存在,硬件自動觸發缺頁異常。
  • 硬件自動跳轉到page fault的處理程序(內核實現注冊好)
  • 內核中的page fault處理程序執行,在其中分配物理內存,然后修改頁表(創建頁表項)
  • 異常處理完畢,返回程序用戶態,繼續執行memset相應的操作。
  • 至此,虛擬內存和物理內存都分配完成,并完成映射。

    另一個角度看,如果malloc分配內存后,一直不使用,那就一直不會分配物理內存,這種內存分配策略叫延遲分配,有其相應的好處,自己理解一下~

    接下來?

    本章,從內存分配的角度看了Linux內核中內存管理的關鍵原理,已經以盡量簡單的方式描述了,希望沒給大家帶來負擔~

    Linux內存管理還涉及其他很多方面,如:

    • 內核自身使用的內存(slab、vmalloc)
    • 伙伴系統
    • 進程地址空間管理

    后面抽空慢慢講,但都希望能盡量簡單,希望大家一看就明白。


    原文地址:?http://happyseeker.github.io/kernel/2016/11/10/memory-management-in-kernel.html

    總結

    以上是生活随笔為你收集整理的闲聊Linux内存管理(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。