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 ...
随机推荐
- 树莓派修改默认pi帐号亲测有效
# 树莓派修改默认pi帐号亲测有效### 1.我的树莓派机型:3B+,系统:Raspbian桌面标准版,连接的屏幕:电视机..###2.打开树莓派LX终端,快捷键:Ctrl+Alt+t ###3.输入 ...
- Django学习day15BBS项目开发3.0
每日测验 """ 今日考题 1.django admin作用及用法 2.media配置如何实现,基于该配置能够做到什么以及需要注意什么 3.阐述博客园为何支持用户自定义个 ...
- 基于React和GraphQL的黛梦设计与实现
写在前面 这是笔者在中秋无聊写着玩的,假期闲暇之余憋出来的帖子.麻雀虽小,但五脏俱全,涉及到的方方面面还是蛮全的.所以就设计了一个黛梦(demo)------ 打通了GraphQL的接口与前端交互的流 ...
- PHP中针对区域语言标记信息的操作
相信大家对 zh_CN 这个东西绝对不会陌生,不管是 PHP 中,还是在我们的网页上,都会见到它的身影.其实这就是指定我们的显示编码是什么国家或者地区的,使用何种语言.对于这种区域语言的标记来说,PH ...
- Mybatis中使用级联查询,一对多的查询
一.需求描述 自己在开发一个小程序的过程中,需要做的一个查询是稍微比较复杂的查询,根据用户信息去查询用户所对应的宠物信息. 一个用户可能对应多个宠物,所以在用户和宠物信息的对应关系就是一对多的关系. ...
- AT2161-[ARC065D]シャッフル/Shuffling【dp】
正题 题目链接:https://www.luogu.com.cn/problem/AT2161 题目大意 长度为\(n\)的\(0/1\)串,\(m\)个区间,你可以按照顺序任意排列区间中的数字,求最 ...
- Docker小白到实战之Docker网络简单了解一下
前言 现在对于Docker容器的隔离性都有所了解了,但对容器IP地址的分配.容器间的访问等还是有点小疑问,如果容器的IP由于新启动导致变动,那又怎么才能保证原有业务不会被影响,这就和网络有挂钩了,接下 ...
- 【vue】获取异步加载后的数据
异步请求的数据,对它做一些处理,需要怎么做呢?? axios 异步请求数据,得到返回的数据, 赋值给变量 info .如果要对 info 的数据做一些处理后再赋值给 hobby ,直接在 axios ...
- Java中的原子操作
Java中的原子操作 原子性:指该操作不能再继续划分为更小的操作. Java中的原子操作包括: 除long和double之外的基本类型的赋值操作 所有引用reference的赋值操作 java.con ...
- 使用 grpcurl 通过命令行访问 gRPC 服务
原文链接: 使用 grpcurl 通过命令行访问 gRPC 服务 一般情况下测试 gRPC 服务,都是通过客户端来直接请求服务端.如果客户端还没准备好的话,也可以使用 BloomRPC 这样的 GUI ...