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 ...
随机推荐
- 3gcms导航,实现当前栏目高亮的办法
<volist name="menu" id="vo" offset="0" length='8' key='k'> <l ...
- Orchar Core 创建一个模块化的ASP.NET Core应用程序
您将构建什么?您将构建一个模块化的ASP.NET Core MVC Web应用程序,类似于Orchard Core附带的示例"Hello World"应用程序.它包括一个Web应用 ...
- ~/.emacs emacs 配置文件
windows ~/.emacs (when (>= emacs-major-version 24) (require 'package) (add-to-list 'package-archi ...
- Windows环境下实现WireShark抓取HTTPS
https 加密传输,Wireshark 没有设置的情况下是没有办法抓到包的 https 的数据包. 设置系统环境变量(SSLKEYLOGFILE) WireShark 设置 SSL 选项 参考文章: ...
- Java集合框架总览
Java集合 Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Collection 接口有 3 种子类型,Lis ...
- 鸿蒙内核源码分析(源码结构篇) | 内核每个文件的含义 | 百篇博客分析OpenHarmony源码 | v18.04
百篇博客系列篇.本篇为: v18.xx 鸿蒙内核源码分析(源码结构篇) | 内核每个文件的含义 | 51.c.h .o 前因后果相关篇为: v08.xx 鸿蒙内核源码分析(总目录) | 百万汉字注解 ...
- vm 将宿主机文件夹 映射至 虚拟机
一.关于centos如何安装(自行百度) 二.设置共享文件夹 添加共享文件夹(关闭虚拟机时操作) 虚拟机->设置->选项->共享文件夹 三.安装vm-tools (请用root用户执 ...
- 2021牛客暑期多校训练营9C-Cells【LGV引理,范德蒙德行列式】
正题 题目链接:https://ac.nowcoder.com/acm/contest/11260/C 题目大意 一个平面上,\(n\)个起点\((0,a_i)\)分别对应终点\((i,0)\),每次 ...
- Python3入门系列之-----range和xrange的区别详解,你明白了吗?
前言 range()是Python的内置函数,用于创建整数的列表,可以生成递增或者递减的数列. xrange也有相同的功能, 今天来看下它们之间的不同. range 函数说明:range([start ...
- 在windoes server2008部署kettle遇到的问题
本机电脑是windows10,在部署ketle时一切顺利,但在windows server2008服务器上部署,各种报错,毕竟线上环境比较复杂-- 问题一:启动kettle的spoon.bat文件时, ...