搜尋
首頁系統教程LinuxLinux kernel記憶體碎片防治技術:深入理解記憶體管理

Linux kernel記憶體碎片防治技術:深入理解記憶體管理

Feb 12, 2024 am 09:54 AM
linuxlinux教程linux系統linux指令shell腳本嵌入式linuxlinux入門linux學習

你是否曾經遇到過在Linux系統中出現的各種記憶體問題?例如記憶體洩漏、記憶體碎片等等。這些問題都可以透過深入理解Linux kernel記憶體碎片防治技術來解決。

Linux kernel内存碎片防治技术:深入理解内存管理

#Linux kernel組織管理實體記憶體的方式是buddy system(夥伴系統),而實體記憶體碎片正式buddy system的弱點之一,為了預防以及解決碎片問題,kernel採取了一些實用技術,這裡將對這些技術進行總結歸納。

1 低記憶體時整合碎片

#從buddy申請記憶體頁,如果找不到合適的頁,則會進行兩步驟調整記憶體的工作,compact和reclaim。前者是為了整合碎片,以獲得更大的連續記憶體;後者是回收不一定必須佔用記憶體的緩衝記憶體。這裡重點了解comact,整個流程大致如下:

__alloc_pages_nodemask
  -> __alloc_pages_slowpath
    -> __alloc_pages_direct_compact
      -> try_to_compact_pages
        -> compact_zone_order
          -> compact_zone
            -> isolate_migratepages
            -> migrate_pages
            -> release_freepages
并不是所有申请不到内存的场景都会compact,首先要满足order大于0,并且gfp_mask携带__

GFP_FS和__GFP_IO;另外,需要zone的剩餘記憶體狀況滿足某一條件,kernel稱之為「碎片指數」(fragmentation index),這個值在0~1000之間,預設碎片指數大於500時才能進行compact,可以透過proc檔extfrag_threshold來調整這個預設值。 fragmentation index透過fragmentation_index函數來計算:

1. /*
2. \* Index is between 0 and 1000
3. *
4. \* 0 => allocation would fail due to lack of memory
5. \* 1000 => allocation would fail due to fragmentation
6. */
7. return 1000 - div_u64( (1000+(div_u64(info->free_pages * 1000ULL, requested))), info->free_blocks_total)

在整合記憶體碎片的過程中,碎片頁只會在本zone的內部移動,將位於zone低位址的頁盡量移到zone的末端。申請新的頁面位置透過compaction_alloc函數實現。

移動過程又分為同步與非同步,記憶體申請失敗後第一次compact將會使用異步,後續reclaim之後將會使用同步。同步過程只會移動當面未使用的頁,非同步過程將遍歷並等待所有MOVABLE的頁使用完成後進行移動。

2 按可移動性組織頁面

#依照可移動性將記憶體頁分為以下三種:
UNMOVABLE:在記憶體中位置固定,不能隨意移動。 kernel分配的記憶體基本上屬於這個型別;
RECLAIMABLE:不能移動,但可以刪除回收。例如檔案映射記憶體;
MOVABLE:可以隨意移動,使用者空間的記憶體基本上屬於這個類型。
申請內存時,根據可移動性,首先在指定類型的空閒頁中申請內存,每個zone的空閒內存組織方式如下:

1. struct zone {
2. ......
3. struct free_area free_area[MAX_ORDER];
4. ......
5. }
6.  
7. struct free_area {
8. struct list_head free_list[MIGRATE_TYPES];
9. unsigned long nr_free;
10. };

當在指定類型的free_area申請不到記憶體時,可以從備用類型挪用,挪用之後的記憶體就會釋放到新指定的類型清單中,kernel把這個過程稱為「盜用」。
備用類型優先權清單如下定義:

1. static int fallbacks[MIGRATE_TYPES][4] = {
2. [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
3. [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
4. \#ifdef CONFIG_CMA
5. [MIGRATE_MOVABLE] = { MIGRATE_CMA, MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
6. [MIGRATE_CMA] = { MIGRATE_RESERVE }, /* Never used */
7. \#else
8. [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
9. \#endif
10. [MIGRATE_RESERVE] = { MIGRATE_RESERVE }, /* Never used */
11. \#ifdef CONFIG_MEMORY_ISOLATION
12. [MIGRATE_ISOLATE] = { MIGRATE_RESERVE }, /* Never used */
13. \#endif
14. };

值得注意的是並非所有場景都適合按可移動性組織頁,當記憶體大小不足以分配到各種類型時,就不適合啟用可移動性。有個全域變數來表示是否啟用,在記憶體初始化時設定:

1. void __ref build_all_zonelists(pg_data_t *pgdat, struct zone *zone)
2. {
3. ......
4. if (vm_total_pages else
7. page_group_by_mobility_disabled = 0;
8. ......
9. }

如果page_group_by_mobility_disabled,則所有記憶體都是不可移動的。
其中有個參數決定了每個記憶體區域至少擁有的頁,pageblock_nr_pages,它的定義如下:

#define pageblock_order HUGETLB_PAGE_ORDER

1. \#else /* CONFIG_HUGETLB_PAGE */
2. /* If huge pages are not used, group by MAX_ORDER_NR_PAGES */
3. \#define pageblock_order (MAX_ORDER-1)
4. \#endif /* CONFIG_HUGETLB_PAGE */
5. \#define pageblock_nr_pages (1UL 

在系統初始化期間,所有頁面都被標記為MOVABLE:

1. void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
2. unsigned long start_pfn, enum memmap_context context)
3. {
4. ......
5. if ((z->zone_start_pfn 

其它可移動性類型的頁都是後來產生的,也就是前面說的「盜取」。在這種情況發生時,通常會「盜取」fallback中更高優先級、更大塊連續的頁,從而避免小碎片的產生。

1. /* Remove an element from the buddy allocator from the fallback list */
2. static inline struct page *
3. __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
4. {
5. ......
6. /* Find the largest possible block of pages in the other list */
7. for (current_order = MAX_ORDER-1; current_order >= order;
8. --current_order) {
9. for (i = 0;; i++) {
10. migratetype = fallbacks[start_migratetype][i];
11. ......
12. }

可以透過/proc/pageteypeinfo查看目前系統各種類型的頁分佈。

3 虛擬可移動記憶體域

#在依據可移動性組織頁的技術之前,還有一個方法已經合入kernel,那就是虛擬記憶體域:ZONE_MOVABLE。基本想法很簡單:把記憶分成兩部分,可移動的和不可移動的。 ###
1. enum zone_type {
2. \#ifdef CONFIG_ZONE_DMA
3. ZONE_DMA,
4. \#endif
5. \#ifdef CONFIG_ZONE_DMA32
6. ZONE_DMA32,
7. \#endif
8. ZONE_NORMAL,
9. \#ifdef CONFIG_HIGHMEM
10. ZONE_HIGHMEM,
11. \#endif
12. ZONE_MOVABLE,
13. __MAX_NR_ZONES
14. };

ZONE_MOVABLE的启用需要指定kernel参数kernelcore或者movablecore,kernelcore用来指定不可移动的内存数量,movablecore指定可移动的内存大小,如果两个都指定,取不可移动内存数量较大的一个。如果都不指定,则不启动。
与其它内存域不同的是ZONE_MOVABLE不关联任何物理内存范围,该域的内存取自高端内存域或者普通内存域。
find_zone_movable_pfns_for_nodes用来计算每个node中ZONE_MOVABLE的内存数量,采用的内存区域通常是每个node的最高内存域,在函数find_usable_zone_for_movable中体现。
在对每个node分配ZONE_MOVABLE内存时,kernelcore会被平均分配到各个Node:
kernelcore_node = required_kernelcore / usable_nodes;
在kernel alloc page时,如果gfp_flag同时指定了__GFP_HIGHMEM和__GFP_MOVABLE,则会从ZONE_MOVABLE内存域申请内存。

总之,Linux kernel内存碎片防治技术是一个非常重要的概念,可以帮助你更好地理解Linux系统中的内存管理。如果你想了解更多关于这个概念的信息,可以查看本文提供的参考资料。

以上是Linux kernel記憶體碎片防治技術:深入理解記憶體管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:良许Linux教程网。如有侵權,請聯絡admin@php.cn刪除
Linux操作是什麼?Linux操作是什麼?Apr 13, 2025 am 12:20 AM

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

使用Linux別名提高自定義命令快捷方式的生產率使用Linux別名提高自定義命令快捷方式的生產率Apr 12, 2025 am 11:43 AM

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

Linux實際上有什麼好處?Linux實際上有什麼好處?Apr 12, 2025 am 12:20 AM

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

在Linux上掌握道德黑客的基本工具和框架在Linux上掌握道德黑客的基本工具和框架Apr 11, 2025 am 09:11 AM

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

如何學習Linux基礎知識?如何學習Linux基礎知識?Apr 10, 2025 am 09:32 AM

Linux基礎學習從零開始的方法包括:1.了解文件系統和命令行界面,2.掌握基本命令如ls、cd、mkdir,3.學習文件操作,如創建和編輯文件,4.探索高級用法如管道和grep命令,5.掌握調試技巧和性能優化,6.通過實踐和探索不斷提陞技能。

Linux最有用的是什麼?Linux最有用的是什麼?Apr 09, 2025 am 12:02 AM

Linux在服務器、嵌入式系統和桌面環境中的應用廣泛。 1)在服務器領域,Linux因其穩定性和安全性成為託管網站、數據庫和應用的理想選擇。 2)在嵌入式系統中,Linux因其高度定制性和高效性而受歡迎。 3)在桌面環境中,Linux提供了多種桌面環境,滿足不同用戶需求。

Linux的缺點是什麼?Linux的缺點是什麼?Apr 08, 2025 am 12:01 AM

Linux的缺點包括用戶體驗、軟件兼容性、硬件支持和學習曲線。 1.用戶體驗不如Windows或macOS友好,依賴命令行界面。 2.軟件兼容性不如其他系統,缺乏許多商業軟件的原生版本。 3.硬件支持不如Windows全面,可能需要手動編譯驅動程序。 4.學習曲線較陡峭,掌握命令行操作需要時間和耐心。

Linux難以學習嗎?Linux難以學習嗎?Apr 07, 2025 am 12:01 AM

Linuxisnothardtolearn,butthedifficultydependsonyourbackgroundandgoals.ForthosewithOSexperience,especiallycommand-linefamiliarity,Linuxisaneasytransition.Beginnersmayfaceasteeperlearningcurvebutcanmanagewithproperresources.Linux'sopen-sourcenature,bas

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1

記事本++7.3.1

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

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

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

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用