转自——http://five.rdaili.com/sohu.com.php?u=Mq3EniVnae0axim7jkGhH0IhA9uho6CQso7R1aYomXWJ9UemfwUQYmKRc82H5yiImrEY&b=3

Linux Kernel 的穩定,有一部份可以歸功於它優良的記憶體管理機制,而探討該機制,有助於瞭解記憶體是如何被 Kernel 所使用,對開發 Linux Driver 的人來說,日後更有許多益處。最重要的是,Linux Kernel 之美是由此開始,優美的設計相當令人著迷。
Linux Kernel 的記憶體管理機制,主要由兩大部份組成:

  • Buddy System
  • Slab Allocator

Buddy System(buddy allocator)


一般的 Operating System Design,Linux Kernel 一樣是以 Page 為記憶體管理的單位,因此設計了一層針對
page(或稱分頁)的管理機制,該機制在 Linux Kernel 裡被稱為『Buddy System (buddy allocator,簡稱
buddy)』,buddy 是 Kernel 最底層的記憶體管理機制,日後所有的記憶體配置,最後都要經過 buddy 才能取得或釋放記憶體。

可以藉由觀察當前 /proc/buddyinfo ,了解目前的記憶體使用情況,當然,是以 page 為單位:

$ cat /proc/buddyinfo
Node 0, zone DMA 76 71 66 50 33 17 5 1 1 1 0
Node 0, zone Normal 22301 6425 45 0 1 1 1 1 1 1 0
Node 0, zone HighMem 97 13 6 10 3 0 2 0 0 0 0

如果沒有什麼意外,/proc/buddyinfo 列會出了三個 zone ,分別是 DMA、Normal、HighMem,這三種 zone 的分類,是以 Physical Memory 位置的範圍而區分,在 IA-32 架構上 為:

  • DMA (16MB以下)
  • Normal (16MB~896MB)
  • HighMem (896MB以上)


過,由於 Buddy System 是一個很抽象且基礎的機制,對一般的 Driver 開發來說,並不是非常好用,而且,對習慣 C
語言的開發者來說,是相當不合情理的存在。體會一下這樣奇怪的習慣:透過 buddy 的 __get_free_pages() 和
free_pages() 等 functions 取得的記憶體,是以 page 為單位來計算(在 IA-32 上大小為 4096
bytes),而不是使用以 1 byte 為單位來配置。

但是,並非不能直接使用 buddy 提供的 functions 做
Linux Driver 的開發,而是有相當的困難性(如果你想全程使用,請先讓小弟尊稱您一下牛人 :P)。一個最簡單可能發生的例子,就是不當使用
page (一個單位數量)的記憶體,易造成記憶體的浪費和 fragmentation。所以,對一般 Driver
的開發者,除非必要,其實不應該要負責處理這樣低階的記憶體問題。

Slab Allocator

有鑑於此,Linux Kernel 就在 buddy 之上,更進一步設計了『智慧型』機制 -『Slab Allocator(簡稱 Slab)』,來確保記憶體分頁的配置效率和完整性,也使其他開發者有更好的 API 和機制可以操作記憶體。

Slab
算是 Kernel 裡最早的一種演算法,事實上,除了 Slab 之外,Linux Kernel
已經實作出數種演算法,以優化記憶體的配置機制。前面提到,Kernel 的底層是以 page 為記憶體配置的單位,因此,哪怕只是需要 1 Byte
的空間,都會佔用一個 page,所以良好的 Slab 演算法,才能盡可能避免記憶體浪費和破碎的問題。截至目前為止,Linux Kernel
所支援的演算法,除 Slab 外另有:

  • SLOB Allocator
  • SLUB Allocator

此外,雖演算法不同,習慣上,在 Linux Kernel 裡還是統稱為『Slab Allocator』,沿用舊有的稱呼以表示該層級的記憶體管理機制。

* 註:Linux Kernel 2.6.23 之後已改用 SLUB 當做預設演算法。

Slab Allocator 實作了一個 cache 的架構(這裡的 cache 並非意指快取),對系統程式下的記憶體需求群組化,以達到管理的目的。一般的程式可以藉由向 Slab 註冊 cache,以得到記憶體的配置。

要知道目前系統上有那些 cache 在使用,可以查看 /proc/slabinfo,亦或者可用指令工具 slabtop 查看。

$ slabtop
Active / Total Objects (% used) : 858912 / 913334 (94.0%)
Active / Total Slabs (% used) : 34472 / 34472 (100.0%)
Active / Total Caches (% used) : 91 / 151 (60.3%)
Active / Total Size (% used) : 124788.54K / 129749.01K (96.2%)
Minimum / Average / Maximum Object : 0.01K / 0.14K / 4096.00K

OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
599140 599140 100% 0.13K 20660 29 82640K dentry
174267 134508 77% 0.05K 2601 67 10404K buffer_head
62448 62337 99% 0.48K 7806 8 31224K ext3_inode_cache
20527 13331 64% 0.28K 1579 13 6316K radix_tree_node
9706 7895 81% 0.08K 211 46 844K vm_area_struct
7980 7779 97% 0.04K 95 84 380K sysfs_dir_cache
7345 7100 96% 0.03K 65 113 260K size-32
6372 5440 85% 0.06K 108 59 432K size-64
5040 4521 89% 0.19K 252 20 1008K filp
4318 3873 89% 0.01K 17 254 68K anon_vma
2576 2546 98% 0.04K 28 92 112K Acpi-Operand
1859 1756 94% 0.02K 11 169 44K Acpi-Namespace
945 924 97% 0.43K 105 9 420K shmem_inode_cache
780 610 78% 0.12K 26 30 104K size-96
744 688 92% 0.50K 93 8 372K size-512
737 710 96% 0.35K 67 11 268K proc_inode_cache
648 130 20% 0.05K 9 72 36K journal_head
572 285 49% 0.33K 52 11 208K inode_cache
493 476 96% 0.13K 17 29 68K idr_layer_cache
470 443 94% 0.38K 47 10 188K sock_inode_cache
405 405 100% 0.44K 45 9 180K UNIX
384 357 92% 1.00K 96 4 384K size-1024
280 180 64% 0.19K 14 20 56K skbuff_head_cache
254 2 0% 0.01K 1 254 4K revoke_table
240 240 100% 0.12K 8 30 32K size-128
234 192 82% 0.05K 3 78 12K task_delay_info
203 121 59% 0.02K 1 203 4K biovec-1
203 3 1% 0.02K 1 203 4K fasync_cache
203 4 1% 0.02K 1 203 4K revoke_record
184 138 75% 0.04K 2 92 8K inotify_watch_cache
180 180 100% 0.19K 9 20 36K size-192

* 註:kmalloc() 所取得的記憶體,會以『size-*』的名稱存在。

當然不止如此,Linux 的記憶體管理還包括例外的特殊管道,如 vmalloc() 等,此外,Kernel Stack 也是一個很重要的機制,可惜短短篇幅無法一下說明完整,日後有時間再行補上。

Linux Kernel 記憶體管理機制之美<转>的更多相关文章

  1. Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式最占cpu的进程

    Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式 2016/12/220 Comments  ######### ps -eo pid,ppid,%mem,%cpu,cmd ...

  2. [ Linux ] 釋放記憶體指令(cache) - 轉載

    1. [Linux]釋放記憶體指令(cache) http://jeffreyy.pixnet.net/blog/post/84333764-%E3%80%90linux%E3%80%91%E9%87 ...

  3. 解開32位元Win 7記憶體4GB限制

    解開32位元Win 7記憶體4GB限制: ReadyFor4GB 檔案下載:ReadyFor4GB https://sites.google.com/a/joytown.tw/bai-jia-zhi/ ...

  4. [ Linux ] [ OS ] [ memory ] Linux 如何查看系統硬體的記憶體(RAM)資訊

    cat /proc/meminfo https://blog.longwin.com.tw/2013/05/linux-ram-memory-info-2013/

  5. Linux kernel中网络设备的管理

    kernel中使用net_device结构来描述网络设备,这个结构是网络驱动及接口层中最重要的结构.该结构不仅描述了接口方面的信息,还包括硬件信息,致使该结构很大很复杂.通过这个结构,内核在底层的网络 ...

  6. Linux Kernel Development有关内存管理

    1 Pages Page的概念来源为处理器Processor的部件MMU(Memory Management Unit),MMU通过设置好的页表(通过设置CR3寄存器,指向页目录所在的物理内存)对内存 ...

  7. Linux Kernel 排程機制介紹

    http://loda.hala01.com/2011/12/linux-kernel-%E6%8E%92%E7%A8%8B%E6%A9%9F%E5%88%B6%E4%BB%8B%E7%B4%B9/ ...

  8. Linux kernel学习-内存管理【转】

    转自:https://zohead.com/archives/linux-kernel-learning-memory-management/ 本文同步自(如浏览不正常请点击跳转):https://z ...

  9. 关于linux kernel slab内存管理的一点思考

    linux kernel 内存管理是个很大的话题,这里记录一点个人关于slab模块的一点思考总结. 有些书把slab介绍成高速缓存,这会让人和cache,特别是cpu cache混淆,造成误解.sla ...

随机推荐

  1. Set代码

    现有一整数集(允许有重复元素),初始为空.我们定义如下操作:add x 把 x 加入集合del x 把集合中所有与 x 相等的元素删除ask x 对集合中元素x的情况询问 对每种操作,我们要求进行如下 ...

  2. ThinkPHP5通过composer安装Workerman安装失败问题

    报错: topthink/think-worker v3.0.2 requires topthink/framework ^6 https://blog.csdn.net/Douz_lungfish/ ...

  3. 数据库删除discuz 部分数据操作

    如何快速清理discuz 3.2 中等待审核的回复数:pre_forum_post_moderate,点击清空 清空回收站的主题帖:DELETE FROM `pre_forum_thread` WHE ...

  4. Dapr + .NET Core实战(四)发布和订阅

    什么是发布-订阅 发布订阅是一种众所周知并被广泛使用的消息传送模式,常用在微服务架构的服务间通信,高并发削峰等情况.但是不同的消息中间件之间存在细微的差异,项目使用不同的产品需要实现不同的实现类,虽然 ...

  5. 电商管理后台 API 接口文档

    1. 电商管理后台 API 接口文档 1.1. API V1 接口说明 接口基准地址:http://127.0.0.1:8888/api/private/v1/ 服务端已开启 CORS 跨域支持 AP ...

  6. VmWare装Linux&Centos步骤

    昨晚一次偶然的机会进入飞哥的直播间,他正在将用虚拟机搭建Linux环境的步骤,自己之前也确实安装过一次,不过没什么系统性总结,过程中有些步骤还需百度查找.于是乎今天决定从零基础在过一遍流程,便是这篇博 ...

  7. Tracking Analyst Tools(Tracking Analyst 工具)

    Tracking Analyst 工具 # Process: 创建追踪图层 arcpy.MakeTrackingLayer_ta("", 输出图层, "NO_TIME_Z ...

  8. 微信小程序内判断是否关注公众号(JAVA)

    微信小程序内判断是否关注公众号(JAVA) 思路来源(第二种): https://blog.csdn.net/Yanheeee/article/details/117295643 /** * 总体思路 ...

  9. 洛谷4631 [APIO2018] Circle selection 选圆圈 (KD树)

    qwq纪念AC450 一开始想这个题想复杂了. 首先,正解的做法是比较麻烦的. qwqq 那么就不如来一点暴力的东西,看到平面上点的距离的题,不难想到\(KD-Tree\) 我们用类似平面最近点对那个 ...

  10. java设计模式_单例模式

    懒汉式 非线程安全 特点:Lazy 初始化.非多线程安全.易实现 描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程.因为没有加锁 synchronized,所以严格意义上它并不算单 ...