[Linux]虛擬地址到物理地址的轉化

[Linux]虛擬地址到物理地址的轉化
@水墨不寫bug


在這里插入圖片描述


文章目錄

  • 一、再次認識地址空間
  • 二、頁表
    • 1、頁表的結構設計
    • 2、頁表節省了空間,省在哪里?
    • 3、頁表的物理實現


一、再次認識地址空間

OS和磁盤交互的內存基本單位是4KB,這4KB通常被稱為內存塊OS對內存管理的粒度精確到塊——4KB為單位。而與之相對的,用戶對內存管理的粒度精確到1byte。在物理內存上,每一個塊都有自己的地址——邏輯塊地址Logical Block Address)。
這里的塊,和文件數據存儲的塊的大小是相同的。OS管理的不是連續的物理內存,物理地址被劃分為4KB為單位的塊,OS通過管理這些塊,間接管理內存。想要管理好這些塊,需要先描述,再組織。在內核中,每一個塊通過一個結構體來管理:

struct page {unsigned long flags;          // 頁狀態標志位(核心字段)union {struct {                  // 頁緩存/匿名頁的通用字段struct list_head lru; // LRU鏈表(用于頁回收)void *mapping;        // 關聯的地址空間(文件或匿名)pgoff_t index;        // 頁在映射中的偏移或交換槽索引unsigned long private;// 私有數據(用途因場景而異)};struct {                  // Slab分配器專用字段union {struct list_head slab_list;struct {         // Partial頁鏈表(用于slab)struct page *next;int pages;   // 當前slab的剩余頁數int pobjects; // 剩余對象數};};struct kmem_cache *slab_cache; // 所屬的slab緩存void *freelist;       // 空閑對象鏈表union {void *s_mem;      // slab第一個對象的地址unsigned long counters; // 引用計數和狀態};};// 其他聯合體分支(如設備頁、大頁等)};atomic_t _refcount;           // 引用計數atomic_t _mapcount;           // 頁表映射計數unsigned long compound_head;  // 復合頁(大頁)的頭頁unsigned int compound_order;   // 復合頁的階數(2^order頁)// ... 其他體系結構相關字段
};

一整個物理內存,有4GB,共1048576個4KB,通過結構體數組來管理:

struct page memory[1048576];//每一個page都有下標

struct page內部都有哪些字段?分別有什么作用?
(1)_refcount-引用計數,表面這個page被多少個進程共享。如果多個進程共享這個page,一旦出現修改數據,需要進行寫時拷貝。
(2)unsigned long flags-標記,32位標識,表面這個頁的屬性:是否有效,是否是臟頁,是否被占用,是否被鎖定。
(3)lru-將頁連接到最近最少使用(LRU) 鏈表,用于頁回收(如kswapd)。LRU_ACTIVE:活躍頁鏈表(近期被訪問過)。LRU_INACTIVE:非活躍頁鏈表(候選回收頁)。


內存中的4KB被稱為頁框文件數據的4KB被稱為頁幀
在這里插入圖片描述
在這里插入圖片描述

同時4KB的大小也方便了內存和磁盤進行存取以塊為單位的文件數據。內存和磁盤進行IO的基本單位理所當然就是4KB。
考慮下面的這幾個例子:

  • (1)即使內存暫時只需要1byte數據,OS也會直接把這1byte所在的4KB直接加載到內存。
  • (2)父子進程對于只讀數據,是共享的;對于任意一方修改了一個全局變量,會發生寫時拷貝OS實際上不是僅僅拷貝了一個變量的大小,而是拷貝了這個變量所在的頁框(4KB)。
  • (3)malloc進行申請空間的時候–malloc(10),底層不是只申請了10字節空間,而是4KB,多余的空間就交給了malloc函數進行維護。
  • (4)共享內存的大小最好就是4KB(4096bytes)的整數倍,如果申請4097bytes,則實際申請了8KB,但是我們用戶能夠使用的大小僅僅是4097bytes—這就造成了空間的浪費。(OS保守起見,多申請的空間不給我們使用
  • (5)page可作為文件的內核級緩沖區,是通過字典樹來把page排序,使得存儲在不同的page內的文件可以方便的恢復。

根據局部性原理這個時間點使用了這1byte,在后續時間點很有可能會使用這1byte附近的數據。 對一個全局變量修改了,很有可能以后要對附近的數據進行修改。所以拷貝4KB是合理的。申請內存一次性申請4KB也是用到了池化思想,提高了效率


二、頁表

1、頁表的結構設計

頁表是一個把進程虛擬地址轉化為物理地址的結構。在x86體系下,物理地址有4GB(2的32次方),如果按照通常的一對一的映射,一個4字節的虛擬地址映射一個4字節的物理地址,一共需要的內存比實際擁有的內存還要多,這十分不合理。所以頁表的映射不是簡單的一對一映射。

在x86體系結構下,一個虛擬地址有32位,這個虛擬地址被分為 10 + 10 + 12
在這里插入圖片描述
前10位 用于在頁目錄內部索引,中間10位用于在頁表中索引,后12位用于在一個頁框內偏移:
在這里插入圖片描述
這樣,我任何一個虛擬地址,都可以通過頁表的機制,找到對應的物理地址!
在這里插入圖片描述

在C/C++中,為什么只要獲取一個變量的首地址就能夠成功訪問這個變量?

因為這個變量還有對應的類型
訪問一個變量,需要首先獲取虛擬地址,通過上述的轉換機制,把虛擬地址1字節轉換到物理地址具體某字節的地址。此外,變量類型在語言層面就告訴了編譯器,編譯器會編譯生成對應的匯編語句:

考慮下面這些語句:

int x = 1234;
int y = *(&x);  // 通過首字節地址讀取值//對應的匯編語句可能就是
mov eax, [0x1000]  ; 從地址 0x1000 開始讀取 4 字節到寄存器 eax
mov [0x2000], eax  ; 將 eax 的值存儲到地址 0x2000

mov eax, [0x1000]:處理器根據地址 0x1000 開始讀取 4 字節(因為 eax 是 4 字節寄存器)。匯編層面會根據指令和寄存器的大小,自動決定讀取的數據寬度。


2、頁表節省了空間,省在哪里?

如果沒有頁表,直接一個物理地址對應一個虛擬地址這樣映射,頁表需要占用的空間就是(以x86為例,一個地址占用的空間為4bytes)(4+4)*4GB = 32GB,需要存儲頁表的空間就已經超過的整機的物理空間大小,顯然不合理。
頁表實際的大小為 頁目錄(4KB) + 所有頁表(4KB * 1024)
4KB+4MB=4100KB = 4.00390625MB
通過上面的計算,實際上就可以通過近乎4MB的空間大小來實現整個頁表結構。于是就把原來的32GB壓縮到了4MB。


3、頁表的物理實現

實際上CPU內部內置了MMU。MMU(內存管理單元,Memory Management Unit) 是計算機硬件中的一個核心組件,通常集成在 CPU 中,主要負責管理內存訪問和地址轉換
上述的頁表的轉換流程就是MMU的工作流程。
CPU引入MMU后,讀取指令、數據需要訪問兩次內存:首先通過PC指針讀取下一條指針的虛擬地址,虛擬地址需要通過查詢頁表得到物理地址,然后訪問該物理地址讀取指令、數據。為了減少因為頻繁查頁表導致的CPU性能下降,MMU引入了TLB,TLB(Translation Lookaside Buffer)可翻譯為“地址轉換后援緩沖器”。TLB就是頁表的Cache,其中存儲了當前最可能(最近)被訪問到的頁表項,其內容是部分頁表項的一個副本。只有在TLB無法完成地址翻譯任務時,才會到內存中查詢頁表,這樣就減少了頁表查詢導致的處理器性能下降。
在這里插入圖片描述


對整體過程而言:在這里插入圖片描述

虛擬到物理地址轉換的詳細流程:

CPU通過PC指針獲取下條指令的虛擬地址,訪問MMU查詢TLB里面是否已經緩存了此次虛擬到物理的映射?如果是,則轉換結束;如果否,則需要訪問頁表。通過CR3寄存器獲取頁表物理地址,通過分級映射查找獲取物理地址,并同時把此次訪問的虛擬到物理的映射緩存到TLB,方便后續的再次映射(如果是循環邏輯,則后續訪問都不需要再次查頁表,十分高效)。


完~
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83323.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83323.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83323.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Kubernetes(K8s)核心架構解析與實用命令大全

在容器化技術席卷全球的今天,Kubernetes(簡稱K8s,以“8”代替“ubernete”八個字母)已成為云原生應用部署和管理的核心基礎設施。作為Google基于內部Borg系統開源打造的容器編排引擎,K8s不僅解決了大規模容器管理的難題…

基于微信小程序的scratch學習系統

博主介紹:java高級開發,從事互聯網行業六年,熟悉各種主流語言,精通java、python、php、爬蟲、web開發,已經做了六年的畢業設計程序開發,開發過上千套畢業設計程序,沒有什么華麗的語言&#xff0…

postgresql 流復制中指定同步的用戶

postgresql 流復制中指定同步的用戶 在創建postgresql流復制的過程中,可以指定用戶名。 主庫pg_hba.conf配置 vi $PGDATA/pg_hba.conf host replication repl 192.168.56.12/32 md5 host all all 0.0.0.0/0 md5主庫創建同步的用戶 # 主庫創建 replicator 流復制…

基于springboot的運動員健康管理系統

博主介紹:java高級開發,從事互聯網行業六年,熟悉各種主流語言,精通java、python、php、爬蟲、web開發,已經做了六年的畢業設計程序開發,開發過上千套畢業設計程序,沒有什么華麗的語言&#xff0…

工具識別系統Python+深度學習+人工智能+卷積神經網絡算法+TensorFlow+圖像識別

一、介紹 工具識別系統,使用Python作為主要編程語言,基于TensorFlow搭建卷積神經網絡算法,通過收集了8種常見的日常工具圖片(“汽油罐(Gasoline Can)”, “錘子(Hammer)”, “鉗子&…

2024 CKA模擬系統制作 | Step-By-Step | 8、題目搭建-創建 Ingress

目錄 ??????免費獲取題庫配套 CKA_v1.31_模擬系統 一、題目 二、核心考點 Ingress 資源定義 Ingress Controller 依賴 服務暴露驗證 網絡層次關系 三、搭建模擬環境 1.創建命名空間 2.安裝ingress ingress-nginx-controller 3.創建hello.yaml并部署 四、總結 …

關于uv 工具的使用總結(uv,conda,pip什么關系)

最近要開發MCP 項目,uv工具使用是官方推薦的方式,逐要了解這個uv工具。整體理解如下: 一.uv工具的基本情況 UV 是一個由 Rust 編寫的現代化 Python 包管理工具,旨在通過極速性能和一體化功能替代傳統工具(如 pip、vi…

嵌入式學習筆記 - 新版Keil軟件模擬時鐘Xtal灰色不可更改的問題

在新版Keil軟件中,模擬時鐘無法修改XTAL頻率,默認只能使用12MHz時鐘。?這是因為Keil MDK從5.36版本開始,參數配置界面不再支持修改系統XTAL頻率,XTAL選項變為灰色,無法修改。這會導致在軟件仿真時出現時間錯誤的問題&…

Spring AI Image Model、TTS,RAG

文章目錄 Spring AI Alibaba聊天模型圖像模型Image Model API接口及相關類實現生成圖像 語音模型Text-to-Speech API概述實現文本轉語音 實現RAG向量化RAGRAG工作流程概述實現基本 RAG 流程 Spring AI Alibaba Spring AI Alibaba實現了與阿里云通義模型的完整適配,…

Java進階---JVM

JVM概述 JVM作用: 負責將字節碼翻譯為機器碼,管理運行時內存 JVM整體組成部分: 類加載系統(ClasLoader):負責將硬盤上的字節碼文件加載到內存中 運行時數據區(RuntimeData Area):負責存儲運行時各種數據 執行引擎(Ex…

數據類型檢測有哪些方式?

typeof 其中數組 對象 null都會判斷為Object,其他正確 typeof 2 // number typeof true //bolean typeof str //string typeof [] //Object typeof function (){} // function typeof {} //object typeof undefined //undefined typeof null // nullinstanceof 判斷…

NodeJS全棧開發面試題講解——P6安全與鑒權

? 6.1 如何防止 SQL 注入 / XSS / CSRF? 面試官您好,Web 安全三大經典問題分別從不同層面入手: 🔸 SQL 注入(Server端) 原理:惡意用戶將 SQL 注入查詢語句拼接,導致數據泄露或破壞…

npm error Cannot find module ‘negotiator‘ 的處理

本想運行npm create vuelatest,但提示: npm error code MODULE_NOT_FOUND npm error Cannot find module negotiator npm error Require stack: npm error - C:\Users\Administrator\AppData\Roaming\nvm\v18.16.1\node_modules\npm\node_modules\tuf-j…

Python爬蟲:AutoScraper 庫詳細使用大全(一個智能、自動、輕量級的網絡爬蟲)

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、AutoScraper概述1.1 AutoScraper介紹1.2 安裝1.3 注意事項二、基本使用方法2.1 創建 AutoScraper 實例2.2 訓練模型2.3 保存和加載模型2.4 數據提取方法2.5 自定義規則三、高級功能3.1 多規則抓取3.2 分頁抓取3.3 代…

【Netty系列】解決TCP粘包和拆包:LengthFieldBasedFrameDecoder

目錄 如何使用? 1. 示例代碼(基于Netty) 2. 關鍵參數解釋 3. 協議格式示例 4. 常見配置場景 場景1:長度字段包含自身 場景2:長度字段在消息中間 5. 注意事項 舉個例子 完整示例:客戶端與服務端交互…

哈爾濱工業大學提出ADSUNet—紅外暗弱小目標鄰幀檢測新框架

ADSUNet: Accumulation-Difference-Based Siamese U-Net for inter-frame Infrared Dim and Small Target Detection 作者單位:哈爾濱工業大學空間光學工程研究中心 引用: Liuwei Zhang, Yuyang Xi, Zhipeng Wang, Wang Zhang, Fanjiao Tan, Qingyu Hou, ADSUNet: A…

Linux開發追蹤(IMX6ULL篇_第一部分)

前言 參數:cortex-A7 698Mhz flash 8GB RAM 512M DDR3 2個100M網口 單核 初期: 一、安裝完虛擬機之后,第一步先設置文件之間可以相互拷貝復制,以及通過CRT連接到虛擬機等 折磨死人了啊啊啊啊啊啊 1、關于SSH怎么安裝…

【萌筆趣棋】網頁五子棋項目測試報告

目錄 一.項目介紹 (一)項目簡介 (二)功能介紹 (三)頁面展示 1.注冊頁面 2.登錄頁面 3.游戲大廳頁面 4.游戲房間頁面(對戰) 二.功能測試 (一)出現的…

知識圖譜增強的大型語言模型編輯

https://arxiv.org/pdf/2402.13593 摘要 大型語言模型(LLM)是推進自然語言處理(NLP)任務的關鍵,但其效率受到不準確和過時知識的阻礙。模型編輯是解決這些挑戰的一個有前途的解決方案。然而,現有的編輯方法…

數據庫,Spring Boot,數據源

您是對的,我之前的回答解釋了Spring Boot在操作MySQL時不一定需要顯式配置指定的數據源類型,因為它有自動配置機制,但沒有直接點明在自動配置情況下“數據源是什么”。 在Spring Boot自動配置機制下,這個“數據源”指的是一個連接…