Linux Kernel 記憶體管理機制之美<转>
转自——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 記憶體管理機制之美<转>的更多相关文章
- Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式最占cpu的进程
Linux 用 ps 與 top 指令找出最耗費 CPU 與記憶體資源的程式 2016/12/220 Comments ######### ps -eo pid,ppid,%mem,%cpu,cmd ...
- [ Linux ] 釋放記憶體指令(cache) - 轉載
1. [Linux]釋放記憶體指令(cache) http://jeffreyy.pixnet.net/blog/post/84333764-%E3%80%90linux%E3%80%91%E9%87 ...
- 解開32位元Win 7記憶體4GB限制
解開32位元Win 7記憶體4GB限制: ReadyFor4GB 檔案下載:ReadyFor4GB https://sites.google.com/a/joytown.tw/bai-jia-zhi/ ...
- [ Linux ] [ OS ] [ memory ] Linux 如何查看系統硬體的記憶體(RAM)資訊
cat /proc/meminfo https://blog.longwin.com.tw/2013/05/linux-ram-memory-info-2013/
- Linux kernel中网络设备的管理
kernel中使用net_device结构来描述网络设备,这个结构是网络驱动及接口层中最重要的结构.该结构不仅描述了接口方面的信息,还包括硬件信息,致使该结构很大很复杂.通过这个结构,内核在底层的网络 ...
- Linux Kernel Development有关内存管理
1 Pages Page的概念来源为处理器Processor的部件MMU(Memory Management Unit),MMU通过设置好的页表(通过设置CR3寄存器,指向页目录所在的物理内存)对内存 ...
- 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/ ...
- Linux kernel学习-内存管理【转】
转自:https://zohead.com/archives/linux-kernel-learning-memory-management/ 本文同步自(如浏览不正常请点击跳转):https://z ...
- 关于linux kernel slab内存管理的一点思考
linux kernel 内存管理是个很大的话题,这里记录一点个人关于slab模块的一点思考总结. 有些书把slab介绍成高速缓存,这会让人和cache,特别是cpu cache混淆,造成误解.sla ...
随机推荐
- CodeForce-807C Success Rate(二分数学)
Success Rate CodeForces - 807C 给你4个数字 x y p q ,要求让你求最小的非负整数b,使得 (x+a)/(y+b)==p/q,同时a为一个整数且0<=a< ...
- PHP设计模式之享元模式
享元模式,"享元"这两个字在中文里其实并没有什么特殊的意思,所以我们要把它拆分来看."享"就是共享,"元"就是元素,这样一来似乎就很容易理解 ...
- 宝塔面板使用PM2命令提示Command Not Found解决方案
1.查看node版本 进入/www/server/nvm/versions/node 查看node版本 2.复制以下代码 以node版本v12.18.1举例 PATH=$PATH:/www/serve ...
- DEDE留言板调用导航的方法
DEDE留言板调用导航的方法 dede里的留言板guestbook.htm用{dede:include filename="../default/head.htm"/}不能自动生成 ...
- Shell系列(6)- 管道符
多命令顺序执行 多命令执行符 格式 作用 ; 命令1 ; 命令2 连接命令:多个命令顺序执行,命令之间没有任何逻辑联系:前面命令报错,后面命令照常执行 && 命令1 && ...
- [转载]用redis实现跨服务器session
地址:http://blog.chinaunix.net/uid-11121450-id-3284875.html 这个月我们新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡, 上 ...
- vivo全球商城-营销价格监控方案的探索
一.背景 现在日常官网商城的运营中有一定概率出现以下两个问题: 1)优惠信息未对齐 官网商城促销优惠的类型越来越多,能影响最终用户实付价的优惠就有抢购.满减.优惠券.代金券等.实际业务操作中存在不同促 ...
- GoLang设计模式08 - 命令模式
命令模式是一种行为型模式.它建议将请求封装为一个独立的对象.在这个对象里包含请求相关的全部信息,因此可以将其独立执行. 在命令模式中有如下基础组件: Receiver:唯一包含业务逻辑的类,命令对象会 ...
- DIVIDEMIX: LEARNING WITH NOISY LABELS AS SEMI-SUPERVISED LEARNING
论文阅读: DIVIDEMIX: LEARNING WITH NOISY LABELS AS SEMI-SUPERVISED LEARNING 作者说明 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- 在Unity中渲染一个黑洞
在Unity中渲染一个黑洞 前言 N年前观看<星际穿越>时,被其中的"卡冈图雅"黑洞所震撼.制作团队表示这是一个最贴近实际的黑洞效果,因为它是通过各种科学理论实现的.当 ...