From 2a0f75178faf061d73ae21d82f712e56022168db Mon Sep 17 00:00:00 2001 From: gatieme Date: Sun, 14 Aug 2016 11:27:36 +0800 Subject: [PATCH] ... --- .../04-buddy/01-buddy_system/README.md | 35 ++++++++++++++++++ .../04-buddy/images/buddy_system.png | Bin 0 -> 21528 bytes 2 files changed, 35 insertions(+) create mode 100644 study/kernel/02-memory/04-buddy/images/buddy_system.png diff --git a/study/kernel/02-memory/04-buddy/01-buddy_system/README.md b/study/kernel/02-memory/04-buddy/01-buddy_system/README.md index d2e8725..504bbc3 100644 --- a/study/kernel/02-memory/04-buddy/01-buddy_system/README.md +++ b/study/kernel/02-memory/04-buddy/01-buddy_system/README.md @@ -149,9 +149,44 @@ default "11"` 上述输出给出了各个内存域中每个分配阶中空闲项的数目, 从左至右, 阶依次升高. 上面给出的信息取自4 GiB物理内存的AMD64系统. +#传统伙伴系统算法 +------- + +在内核分配内存时, 必须记录页帧的已分配或空闲状态, 以免两个进程使用同样的内存区域. 由于内存分配和释放非常频繁, 内核还必须保证相关操作尽快完成. 内核可以只分配完整的页帧. 将内存划分为更小的部分的工作, 则委托给用户空间中的标准库. 标准库将来源于内核的页帧拆分为小的区域, 并为进程分配内存. +内核中很多时候要求分配连续页. 为快速检测内存中的连续区域, 内核采用了一种古老而历经检验的技术: **伙伴系统** +系统中的空闲内存块总是两两分组, 每组中的两个内存块称作伙伴. 伙伴的分配可以是彼此独立的. 但如果两个伙伴都是空闲的, 内核会将其合并为一个更大的内存块, 作为下一层次上某个内存块的伙伴. + +下图示范了该系统, 图中给出了一对伙伴, 初始大小均为8页. 即系统中所有的页面都是8页的. + +![伙伴系统](../images/buddy_system.png) + +内核对所有大小相同的伙伴(1、2、4、8、16或其他数目的页),都放置到同一个列表中管理. 各有8页的一对伙伴也在相应的列表中. + +如果系统现在需要8个页帧, 则将16个页帧组成的块拆分为两个伙伴. 其中一块用于满足应用程序的请求, 而剩余的8个页帧则放置到对应8页大小内存块的列表中. + +如果下一个请求只需要2个连续页帧, 则由8页组成的块会分裂成2个伙伴, 每个包含4个页帧. 其中一块放置回伙伴列表中,而另一个再次分裂成2个伙伴, 每个包含2页。其中一个回到伙伴系统,另一个则传递给应用程序. + +在应用程序释放内存时, 内核可以直接检查地址, 来判断是否能够创建一组伙伴, 并合并为一个更大的内存块放回到伙伴列表中, 这刚好是内存块分裂的逆过程。这提高了较大内存块可用的可能性. + +在系统长期运行时,服务器运行几个星期乃至几个月是很正常的,许多桌面系统也趋向于长期开机运行,那么会发生称为碎片的内存管理问题。频繁的分配和释放页帧可能导致一种情况:系统中有若干页帧是空闲的,但却散布在物理地址空间的各处。换句话说,系统中缺乏连续页帧组成的较大的内存块,而从性能上考虑,却又很需要使用较大的连续内存块。通过伙伴系统可以在某种程度上减少这种效应,但无法完全消除。如果在大块的连续内存中间刚好有一个页帧分配出去,很显然这两块空闲的内存是无法合并的. + +在内核版本2.6.24之后, 增加了一些有效措施来防止内存碎片 +# 避免碎片 +------- + +在第1章给出的简化说明中, 一个双链表即可满足伙伴系统的所有需求. 在内核版本2.6.23之前, 的确是这样. 但在内核2.6.24开发期间, 内核开发者对伙伴系统的争论持续了相当长时间. 这是因为伙伴系统是内核最值得尊敬的一部分,对它的改动不会被大家轻易接受 + +##依据可移动性组织页 +------- + +伙伴系统的基本原理已经在第1章中讨论过,其方案在最近几年间确实工作得非常好。但在Linux内存管理方面,有一个长期存在的问题:在系统启动并长期运行后,物理内存会产生很多碎片。该情形如图3-24所示 + +假定内存由60页组成,这显然不是超级计算机,但用于示例却足够了。左侧的地址空间中散布着空闲页。尽管大约25%的物理内存仍然未分配,但最大的连续空闲区只有一页. 这对用户空间应用程序没有问题:其内存是通过页表映射的,无论空闲页在物理内存中的分布如何,应用程序看到的内存 +似乎总是连续的。右图给出的情形中,空闲页和使用页的数目与左图相同,但所有空闲页都位于一个 +连续区中。 # 分配器API ------- diff --git a/study/kernel/02-memory/04-buddy/images/buddy_system.png b/study/kernel/02-memory/04-buddy/images/buddy_system.png new file mode 100644 index 0000000000000000000000000000000000000000..d8aef75c98ce368120cef97da89de6dd630e0ff4 GIT binary patch literal 21528 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 literal 0 HcmV?d00001