掌握Linux記憶體管理,讓你的程式效能再提升!
Linux作為一款廣泛應用於伺服器和嵌入式裝置的作業系統,佔據了越來越大的市場份額。在這些場景下,記憶體管理是至關重要的,因為它直接影響到系統的效能和穩定性,特別是對於程式設計師來說更是如此。對於想要在Linux平台上開發高效能應用程式的程式設計師來說,精通Linux記憶體管理是必須的。今天我們將介紹一篇文章,這篇文章是每個程式設計師都應該閱讀的:Linux記憶體管理。
對於記憶體部分需要知道:
- 位址映射
- # 記憶體管理的方式
- 缺頁異常
先來看一些基本的知識,在流程看來,記憶體分為核心態和使用者態兩部分,經典比例如下:
#
從用戶態到內核態一般透過系統呼叫、中斷來實現。使用者態的記憶體被劃分為不同的區域用於不同的目的:

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

下面來仔細看這些記憶體是如何管理的。
位址
在Linux內部的位址的對應過程為邏輯位址–>線性位址–>實體位址,實體位址最簡單:位址匯流排中傳送的數位訊號,而線性位址和邏輯位址所表示的則是一種轉換規則,線性位址規則如下:

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

在Linux中的邏輯位址等於線性位址,也就是說Inter為了相容把事情搞得很複雜,Linux簡化順便偷個懶。
記憶體管理的方式
#在系統boot的時候會去探測內存的大小和情況,在建立複雜的結構之前,需要用一個簡單的方式來管理這些內存,這就是bootmem,簡單來說就是位圖,不過其中也有一些優化的思路。
bootmem再怎麼優化,效率都不高,在要分配記憶體的時候畢竟是要去遍歷,buddy系統剛好能解決這個問題:在內部保存一些2的冪次大小的空閒記憶體片段,如果要分配3page,去4page的清單裡面取一個,分配3個之後將剩下的1個放回去,記憶體釋放的過程剛好是一個逆過程。用一個圖表來表示:

可以看到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來解決小物件的分配:

在運行時,slab向buddy「批發」一些內存,加工切塊以後「散賣」出去。隨著大規模多處理器系統和NUMA系統的廣泛應用,slab終於暴露出不足:
- 複雜的隊列管理
- 管理資料和佇列儲存開銷較大
- # 長時間運行partial佇列可能會非常長
- # 對NUMA支援非常複雜
為了解決這些高手們開發了slub:改造page結構來削減slab管理結構的開銷、每個CPU都有一個本地活動的slab(kmem_cache_cpu)等。對於小型的嵌入式系統存在一個slab模擬層slob,在這種系統中它更有優勢。
小内存的问题算是解决了,但还有一个大内存的问题:用伙伴系统分配10 x 4KB的数据时,会去16 x 4KB的空闲列表里面去找(这样得到的物理内存是连续的),但很有可能系统里面有内存,但是伙伴系统分配不出来,因为他们被分割成小的片段。那么,vmalloc就是要用这些碎片来拼凑出一个大内存,相当于收集一些“边角料”,组装成一个成品后“出售”:

之前的内存都是直接映射的,第一次感觉到页式管理的存在:D 另外对于高端内存,提供了kmap方法为page分配一个线性地址。
进程由不同长度的段组成:代码段、动态库的代码、全局变量和动态产生数据的堆、栈等,在Linux中为每个进程管理了一套虚拟地址空间:

在我们写代码malloc完以后,并没有马上占用那么大的物理内存,而仅仅是维护上面的虚拟地址空间而已,只有在真正需要的时候才分配物理内存,这就是COW(COPY-ON-WRITE:写时复制)技术,而物理分配的过程就是最复杂的缺页异常处理环节了,下面来看!
缺页异常
在实际需要某个虚拟内存区域的数据之前,和物理内存之间的映射关系不会建立。如果进程访问的虚拟地址空间部分尚未与页帧关联,处理器自动引发一个缺页异常。在内核处理缺页异常时可以拿到的信息如下:
- cr2:访问到线性地址
- err_code:异常发生时由控制单元压入栈中,表示发生异常的原因
- regs:发生异常时寄存器的值
处理的流程如下:

发生缺页异常的时候,可能因为不常使用而被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中文網其他相關文章!

學習Linux並不難。 1.Linux是一個開源操作系統,基於Unix,廣泛應用於服務器、嵌入式系統和個人電腦。 2.理解文件系統和權限管理是關鍵,文件系統是層次化的,權限包括讀、寫和執行。 3.包管理系統如apt和dnf使得軟件管理方便。 4.進程管理通過ps和top命令實現。 5.從基本命令如mkdir、cd、touch和nano開始學習,再嘗試高級用法如shell腳本和文本處理。 6.常見錯誤如權限問題可以通過sudo和chmod解決。 7.性能優化建議包括使用htop監控資源、清理不必要文件和使用sy

Linux管理員的平均年薪在美國為75,000至95,000美元,歐洲為40,000至60,000歐元。提升薪資可以通過:1.持續學習新技術,如雲計算和容器技術;2.積累項目經驗並建立Portfolio;3.建立職業網絡,拓展人脈。

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

互聯網運行不依賴單一操作系統,但Linux在其中扮演重要角色。 Linux廣泛應用於服務器和網絡設備,因其穩定性、安全性和可擴展性受歡迎。

Linux操作系統的核心是其命令行界面,通過命令行可以執行各種操作。 1.文件和目錄操作使用ls、cd、mkdir、rm等命令管理文件和目錄。 2.用戶和權限管理通過useradd、passwd、chmod等命令確保系統安全和資源分配。 3.進程管理使用ps、kill等命令監控和控制系統進程。 4.網絡操作包括ping、ifconfig、ssh等命令配置和管理網絡連接。 5.系統監控和維護通過top、df、du等命令了解系統運行狀態和資源使用情況。

介紹 Linux是一個強大的操作系統,由於其靈活性和效率,開發人員,系統管理員和電源用戶都喜歡。但是,經常使用長而復雜的命令可能是乏味的

Linux適用於服務器、開發環境和嵌入式系統。 1.作為服務器操作系統,Linux穩定高效,常用於部署高並發應用。 2.作為開發環境,Linux提供高效的命令行工具和包管理系統,提升開發效率。 3.在嵌入式系統中,Linux輕量且可定制,適合資源有限的環境。

簡介:通過基於Linux的道德黑客攻擊數字邊界 在我們越來越相互聯繫的世界中,網絡安全至關重要。 道德黑客入侵和滲透測試對於主動識別和減輕脆弱性至關重要


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

WebStorm Mac版
好用的JavaScript開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

記事本++7.3.1
好用且免費的程式碼編輯器