所以我想知道當我打電話時malloc到底發生了什么?由于 malloc 必須是一個包裝器,因此必須在其中呼叫一些其他函式可能是brk什么,但是在 brk 內部會發生什么,我所知道的所有這些都是記憶體分配函式,它們分配記憶體并在成功時回傳非零值。但是什么是記憶體管理。
因此,如果我假設記憶體管理只是將記憶體大小與當前值保持一致。因此,例如,如果我有兩個 malloc 呼叫,它們都是分配 10 個整數,每個分配的大小都將與某個表中的當前值保持一致。那個表叫什么。所以假設我正在實作一個記憶體管理單元是有意義的。Linux中是否有一些標準可以稱為這個表的結構,我可以在一個系統中有多個記憶體管理單元意味著有一個父MMU,而我的MMU只是依賴于一些標準功能
uj5u.com熱心網友回復:
在 Linux 上呼叫 malloc() 時,會呼叫 libc(C 標準庫實作)中的瘦包裝器。這個瘦包裝器通常會使用 mmap 系統呼叫來分配記憶體。
在 x86-64 上,系統呼叫是syscall在匯編中使用以及 SysV ABI 中指定的常規暫存器中的一些引數進行的。
該syscall指令使處理器在這些處理器的 STAR64 MSR 暫存器中指定的地址處從用戶模式跳轉到超級用戶模式。
在 Linux 上,它將跳轉到檔案 entry_64.S 的第一條指令。該匯編檔案將進行多次檢查以確定用戶模式要求什么,并在某些暫存器中回傳一個值。
對于 mmap,系統呼叫正在尋找分配物理記憶體并修改頁表,以便來自下一部分可用虛擬記憶體的轉換將轉換到物理記憶體中的這些位置。有關更多資訊,您可以在每個程式分配固定堆疊大小?誰定義了每個運行的應用程式的堆疊記憶體量?. 動態分配是在所謂的堆上完成的,它可以隨著可用記憶體的增長而增長。
libc 庫實際上會自行分配記憶體以確定分配給用戶模式行程的記憶體量。這是必需的,因為現代 x86-64 上的分配粒度是一個 4kb 頁面。因此,libc 庫將跟蹤分配的頁面的所謂“競技場”,以嘗試在這些頁面中為您提供新的分配,而不是請求新的分配。
此外,Linux 內核會跟蹤在 PCB(task_struct)中為您的行程分配的記憶體,該mm欄位本身就是一個復雜的結構。
編輯
我想知道是否每次分配都針對特定的 tid/pid,并且分配的記憶體加上 pid 保存在某個表中。這是MMU的作品嗎
要理解此答案中的概念,您需要了解分頁。通過分頁,每個行程/執行緒都有自己的一組頁表。每組頁表都允許訪問相當大的整個虛擬記憶體空間,因為在大多數作業系統上,使用 48 位允許尋址 2^48 位元組(這由 CPU 架構決定,但也有 57 位地址大多數作業系統不使用的較新 CPU 上的可用空間)。
MMU 對行程/執行緒或 PID 一無所知。它盲目地獲取虛擬地址并穿過頁表將它們轉換為物理地址。頁表中的大多數條目都被清零以確保訪問將觸發硬體中斷(頁面錯誤)。在頁面錯誤時,Linux 內核將跨越mm觸發頁面錯誤的行程的欄位,如果該行程的記憶體訪問超出該區域,則終止該行程。每個內核都可以看到完整的物理地址空間,并且可能有自己的 MMU。MMU 現在確實有 PCID,但它主要與快取相關,與您的問題無關。
處理器的每個內核一次只運行一個執行緒,并且有自己的 CR3 暫存器。作業系統知道哪個行程在哪里運行以及在哪個內核上運行,因為不同的故障處理程式在內核模式下運行并且可以訪問內核的所有全域結構,這些結構識別哪個行程在哪里運行等等。使用頁表的翻譯從 CR3 開始登記。作業系統只是將 CR3 暫存器的值保存在 PCB 中,并在背景關系切換時恢復它。
希望這很清楚!有關分頁的更多資訊,請參閱:究竟什么是分頁?作業系統開發。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/432868.html
上一篇:比較兩個檔案并根據條件輸出結果
