目錄
記憶體分配是如何完成的? " >記憶體分配是如何完成的?
第一個系統呼叫:brk" >第一個系統呼叫:brk
位址空間佈局隨機化:ASLR" >位址空間佈局隨機化:ASLR
第二个系统调用:mmap" >第二个系统调用:mmap
Linux 中内存分配的重要性" >Linux 中内存分配的重要性
首頁 系統教程 Linux Linux 上記憶體分配的工作原理

Linux 上記憶體分配的工作原理

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

了解 Linux 記憶體分配的細節非常重要,尤其是在核心和系統架構中。讓我們深入了解 Linux 記憶體分配並了解幕後發生的事情。

在電腦中,要讓進程可執行,就需要將其放置在記憶體中。為此,必須將欄位分配給記憶體中的進程。記憶體分配是一個需要注意的重要問題,尤其是在核心和系統架構中。

讓我們詳細了解 Linux 記憶體分配,並了解幕後發生的事情。

記憶體分配是如何完成的?

大多數軟體工程師不知道這個過程的細節。但如果你是系統程式設計師候選人,你應該對它了解更多。在看分配過程的時候,有必要對 Linux 和glibc庫做一個小細節。

當應用程式需要記憶體時,它們必須從作業系統請求它。來自核心的這個請求自然需要係統呼叫。您不能在使用者模式下自己分配記憶體。

**malloc()**系列函數負責 C 語言中的記憶體分配。這裡要問的問題是 malloc() 作為 glibc 函數是否進行直接系統呼叫。

Linux 核心中沒有稱為 malloc 的系統呼叫。但是,對於應用程式的記憶體需求有兩個系統調用,它們是brkmmap

由於您將透過 glibc 函數在應用程式中請求內存,您可能想知道此時 glibc 正在使用哪些系統呼叫。答案是兩者兼具。

Linux 上内存分配的工作原理

第一個系統呼叫:brk

#每個行程都有一個連續的資料欄位。透過 brk 系統調用,增加了決定資料域限制的程式中斷值,並執行了分配過程。

儘管使用這種方法分配記憶體非常快,但並非總是可以將未使用的空間傳回系統。

例如,假設您透過 malloc() 函數為 brk 系統呼叫分配了五個字段,每個字段大小為 16KB。當您完成其中第二個欄位時,無法傳回相關資源(解除指派)以便系統可以使用它。因為如果您減少位址值以顯示第二個欄位的開始位置,並呼叫 brk,您將完成第三、四個和五個欄位的釋放。

為了防止這種情況下的記憶體遺失,glibc 中的malloc 實作會監控進程資料欄位中分配的位置,然後透過free() 函數指定將其傳回給系統,以便系統可以將空閒空間用於進一步的記憶體分配。

也就是說,在分配了5 個16KB 的區域之後,如果用free() 函數傳回第二個區域,過一段時間再請求另一個16KB 的區域,而不是透過brk 系統呼叫擴大資料區域,之前的地址是回來。

但是,如果新要求的區域大於 16KB,則資料區域將透過 brk 系統呼叫指派新區域來擴大,因為區域 2 無法使用。雖然二號區域沒有使用,但由於大小不同,應用程式無法使用它。因為這樣的場景,有一種情況叫做內部碎片,實際上你很少能充分利用記憶體的所有部分。

為了更好地理解,請嘗試編譯並執行以下範例應用程式:

#include 
#include 
#include 
int main(int argc, char* argv[])
{
        char *ptr[7];
        int n;
        printf("Pid of %s: %d", argv[0], getpid());
        printf("Initial program break   : %p", sbrk(0));
        for(n=0; nprintf("After 5 x 16kB malloc   : %p", sbrk(0));
        free(ptr[1]);
        printf("After free of second 16kB       : %p", sbrk(0));
        ptr[5] = malloc(16 * 1024);
        printf("After allocating 6th of 16kB    : %p", sbrk(0));
        free(ptr[5]);
        printf("After freeing last block        : %p", sbrk(0));
        ptr[6] = malloc(18 * 1024);
        printf("After allocating a new 18kB     : %p", sbrk(0));
        getchar();
        return 0;
}
登入後複製

執行應用程式時,您將獲得類似於以下輸出的結果:

Pid of ./a.out: 31990
Initial program break   : 0x55ebcadf4000
After 5 x 16kB malloc   : 0x55ebcadf4000
After free of second 16kB       : 0x55ebcadf4000
After allocating 6th of 16kB    : 0x55ebcadf4000
After freeing last block        : 0x55ebcadf4000
After allocating a new 18kB     : 0x55ebcadf4000
登入後複製
Linux 上内存分配的工作原理

有 strace 的 brk 的輸出如下:

brk(NULL)                               = 0x5608595b6000
brk(0x5608595d7000)                     = 0x5608595d7000
登入後複製

如您所見,0x21000 已新增至資料欄位的結束位址。您可以從值 0x5608595d7000 中理解這一點。因此分配了大約 0x21000 或 132KB 的記憶體。

這裡有兩點要考慮。第一種是分配超過範例程式碼中指定的數量。另一個是哪一行程式碼導致了提供分配的 brk 呼叫。

位址空間佈局隨機化:ASLR

當您一個接一個地執行上述範例應用程式時,您每次都會看到不同的位址值。以這種方式隨機更改位址空間會使安全攻擊的工作變得非常複雜,並提高了軟體的安全性。

但是,在 32 位架构中,通常使用 8 位来随机化地址空间。增加位数将不合适,因为剩余位上的可寻址区域将非常低。此外,仅使用 8 位组合不会使攻击者的事情变得足够困难。

另一方面,在 64 位体系结构中,由于可以为 ASLR 操作分配的位太多,因此提供了更大的随机性,并且提高了安全程度。

Linux 内核还支持基于 Android 的设备,并且 ASLR 功能在 Android 4.0.3 及更高版本上完全激活。即使仅出于这个原因,也可以说 64 位智能手机比 32 位版本具有显着的安全优势。

通过使用以下命令暂时禁用 ASLR 功能,之前的测试应用程序每次运行时都会返回相同的地址值:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
登入後複製

要将其恢复到以前的状态,在同一个文件中写入 2 而不是 0 就足够了。

第二个系统调用:mmap

mmap 是 Linux 上用于内存分配的第二个系统调用。通过 mmap 调用,内存中任何区域的空闲空间都映射到调用进程的地址空间。

在以这种方式完成的内存分配中,当您想使用前面 brk 示例中的 free() 函数返回第二个 16KB 分区时,没有机制可以阻止此操作。从进程的地址空间中删除相关的内存段。它被标记为不再使用并返回系统。

因为与使用 brk 相比,使用 mmap 的内存分配非常慢,所以需要分配 brk。

使用 mmap,内存的任何空闲区域都映射到进程的地址空间,因此在该进程完成之前,已分配空间的内容被重置。如果没有以这种方式进行重置,则属于先前使用相关内存区域的进程的数据也可以被下一个不相关的进程访问。这样就不可能谈论系统中的安全性。

Linux 中内存分配的重要性

内存分配非常重要,尤其是在优化和安全问题上。如上面的示例所示,不完全理解此问题可能意味着破坏系统的安全性。

甚至许多编程语言中存在的类似于 push 和 pop 的概念也是基于内存分配操作的。能够很好地使用和掌握系统内存对于嵌入式系统编程和开发安全和优化的系统架构都是至关重要的。

如果您还想涉足 Linux 内核开发,请考虑首先掌握 C 编程语言。

综上所述,Linux 中的内存分配是一个需要注意和理解的重要问题,特别是对于程序员、内核开发人员和系统架构师而言。熟练掌握内存分配可以提高软件性能和安全性,并在嵌入式系统编程和系统架构方面提供更好的支持。同时,C 编程语言的掌握也是涉足 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)

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

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

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

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

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

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

vscode是什麼 vscode是乾什麼用的 vscode是什麼 vscode是乾什麼用的 Apr 15, 2025 pm 06:45 PM

VS Code 全稱 Visual Studio Code,是一個由微軟開發的免費開源跨平台代碼編輯器和開發環境。它支持廣泛的編程語言,提供語法高亮、代碼自動補全、代碼片段和智能提示等功能以提高開發效率。通過豐富的擴展生態系統,用戶可以針對特定需求和語言添加擴展程序,例如調試器、代碼格式化工具和 Git 集成。 VS Code 還包含直觀的調試器,有助於快速查找和解決代碼中的 bug。

VSCode怎麼用 VSCode怎麼用 Apr 15, 2025 pm 11:21 PM

Visual Studio Code (VSCode) 是一款跨平台、開源且免費的代碼編輯器,由微軟開發。它以輕量、可擴展性和對眾多編程語言的支持而著稱。要安裝 VSCode,請訪問官方網站下載並運行安裝程序。使用 VSCode 時,可以創建新項目、編輯代碼、調試代碼、導航項目、擴展 VSCode 和管理設置。 VSCode 適用於 Windows、macOS 和 Linux,支持多種編程語言,並通過 Marketplace 提供各種擴展。它的優勢包括輕量、可擴展性、廣泛的語言支持、豐富的功能和版

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

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

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

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

See all articles