首頁 系統教程 Linux 掌握Linux記憶體管理,讓你的程式效能再提升!

掌握Linux記憶體管理,讓你的程式效能再提升!

Feb 13, 2024 pm 04:40 PM
linux linux教程 linux系統 linux指令 shell腳本 嵌入式linux linux入門 linux學習

Linux作為一款廣泛應用於伺服器和嵌入式裝置的作業系統,佔據了越來越大的市場份額。在這些場景下,記憶體管理是至關重要的,因為它直接影響到系統的效能和穩定性,特別是對於程式設計師來說更是如此。對於想要在Linux平台上開發高效能應用程式的程式設計師來說,精通Linux記憶體管理是必須的。今天我們將介紹一篇文章,這篇文章是每個程式設計師都應該閱讀的:Linux記憶體管理。
對於記憶體部分需要知道:

  1. 位址映射
  2. # 記憶體管理的方式
  3. 缺頁異常

先來看一些基本的知識,在流程看來,記憶體分為核心態和使用者態兩部分,經典比例如下:

掌握Linux記憶體管理,讓你的程式效能再提升!
# 從用戶態到內核態一般透過系統呼叫、中斷來實現。使用者態的記憶體被劃分為不同的區域用於不同的目的:

掌握Linux記憶體管理,讓你的程式效能再提升!

當然內核態也不會無差別地使用,所以,其分割如下:

掌握Linux記憶體管理,讓你的程式效能再提升!

下面來仔細看這些記憶體是如何管理的。

位址

在Linux內部的位址的對應過程為邏輯位址–>線性位址–>實體位址,實體位址最簡單:位址匯流排中傳送的數位訊號,而線性位址和邏輯位址所表示的則是一種轉換規則,線性位址規則如下:

掌握Linux記憶體管理,讓你的程式效能再提升!

這部分由MMU完成,其中涉及到主要的暫存器有CR0、CR3。機器指令中出現的是邏輯位址,邏輯位址規則如下:

掌握Linux記憶體管理,讓你的程式效能再提升!

在Linux中的邏輯位址等於線性位址,也就是說Inter為了相容把事情搞得很複雜,Linux簡化順便偷個懶。

記憶體管理的方式

#在系統boot的時候會去探測內存的大小和情況,在建立複雜的結構之前,需要用一個簡單的方式來管理這些內存,這就是bootmem,簡單來說就是位圖,不過其中也有一些優化的思路。

bootmem再怎麼優化,效率都不高,在要分配記憶體的時候畢竟是要去遍歷,buddy系統剛好能解決這個問題:在內部保存一些2的冪次大小的空閒記憶體片段,如果要分配3page,去4page的清單裡面取一個,分配3個之後將剩下的1個放回去,記憶體釋放的過程剛好是一個逆過程。用一個圖表來表示:

掌握Linux記憶體管理,讓你的程式效能再提升!

可以看到0、4、5、6、7都是正在使用的,那麼,1、2被釋放的時候,他們會合併嗎?

static inline unsigned long
__find_buddy_index(unsigned long page_idx, unsigned int order)
{
    return page_idx ^ (1 
登入後複製

從上面這段程式碼可以看到,0、1是buddy,2、3是buddy,雖然1、2相鄰,但他們不是。記憶體碎片是系統運作的大敵,夥伴系統機制可以在一定程度上防止碎片~~另外,我們可以透過cat /proc/buddyinfo取得到各order中的空閒的頁數。

夥伴系統每次分配記憶體都是以頁(4KB)為單位的,但係統運作的時候使用的絕大部分的資料結構都是很小的,為一個小物件分配4KB顯然是不划算了。 Linux中使用slab來解決小物件的分配:

掌握Linux記憶體管理,讓你的程式效能再提升!

在運行時,slab向buddy「批發」一些內存,加工切塊以後「散賣」出去。隨著大規模多處理器系統和NUMA系統的廣泛應用,slab終於暴露出不足:

  1. 複雜的隊列管理
  2. 管理資料和佇列儲存開銷較大
  3. # 長時間運行partial佇列可能會非常長
  4. # 對NUMA支援非常複雜

為了解決這些高手們開發了slub:改造page結構來削減slab管理結構的開銷、每個CPU都有一個本地活動的slab(kmem_cache_cpu)等。對於小型的嵌入式系統存在一個slab模擬層slob,在這種系統中它更有優勢。

小内存的问题算是解决了,但还有一个大内存的问题:用伙伴系统分配10 x 4KB的数据时,会去16 x 4KB的空闲列表里面去找(这样得到的物理内存是连续的),但很有可能系统里面有内存,但是伙伴系统分配不出来,因为他们被分割成小的片段。那么,vmalloc就是要用这些碎片来拼凑出一个大内存,相当于收集一些“边角料”,组装成一个成品后“出售”:

掌握Linux記憶體管理,讓你的程式效能再提升!

之前的内存都是直接映射的,第一次感觉到页式管理的存在:D 另外对于高端内存,提供了kmap方法为page分配一个线性地址。

进程由不同长度的段组成:代码段、动态库的代码、全局变量和动态产生数据的堆、栈等,在Linux中为每个进程管理了一套虚拟地址空间:

掌握Linux記憶體管理,讓你的程式效能再提升!

在我们写代码malloc完以后,并没有马上占用那么大的物理内存,而仅仅是维护上面的虚拟地址空间而已,只有在真正需要的时候才分配物理内存,这就是COW(COPY-ON-WRITE:写时复制)技术,而物理分配的过程就是最复杂的缺页异常处理环节了,下面来看!

缺页异常

在实际需要某个虚拟内存区域的数据之前,和物理内存之间的映射关系不会建立。如果进程访问的虚拟地址空间部分尚未与页帧关联,处理器自动引发一个缺页异常。在内核处理缺页异常时可以拿到的信息如下:

  1. cr2:访问到线性地址
  2. err_code:异常发生时由控制单元压入栈中,表示发生异常的原因
  3. regs:发生异常时寄存器的值

处理的流程如下:

掌握Linux記憶體管理,讓你的程式效能再提升!

发生缺页异常的时候,可能因为不常使用而被swap到磁盘上了,swap相关的命令如下:

swapon                        开启swap
swapoff                       关闭swap
/proc/sys/vm/swapiness        分值越大越积极使用swap,可以修改/etc/sysctl.conf中添加vm.swappiness=xx[1-100]来修改
登入後複製

如果内存是mmap映射到内存中的,那么在读、写对应内存的时候也会产生缺页异常。

在Linux中,内存管理是一个复杂的主题,但是如果程序员能够理解并充分利用它,他们可以极大地提高他们的程序的性能和可靠性。在本文中,我们介绍了Linux内存管理的基本知识、虚拟内存的概念、内存映射文件以及交换空间等。此外,我们还介绍了一些有助于程序员优化内存使用的技巧和工具。现在,不要再让程序的性能拖慢了你的项目,去掌握Linux内存管理吧!

以上是掌握Linux記憶體管理,讓你的程式效能再提升!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode 無法安裝擴展 vscode 無法安裝擴展 Apr 15, 2025 pm 07:18 PM

VS Code擴展安裝失敗的原因可能包括:網絡不穩定、權限不足、系統兼容性問題、VS Code版本過舊、殺毒軟件或防火牆干擾。通過檢查網絡連接、權限、日誌文件、更新VS Code、禁用安全軟件以及重啟VS Code或計算機,可以逐步排查和解決問題。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

vscode 可以用於 mac 嗎 vscode 可以用於 mac 嗎 Apr 15, 2025 pm 07:36 PM

VS Code 可以在 Mac 上使用。它具有強大的擴展功能、Git 集成、終端和調試器,同時還提供了豐富的設置選項。但是,對於特別大型項目或專業性較強的開發,VS Code 可能會有性能或功能限制。

See all articles