免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 16970 | 回复: 21

[内存管理] 对内存管理的思考 [复制链接]

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
发表于 2010-08-24 16:17 |显示全部楼层
内核的虚拟内存被连续映射到最低端的物理内存。这是所有问题的开始。

为什么要把内核的虚拟地址空间连续地映射到物理内存最低端?这个根本不是个问题。开发人员或是出于效率的原因或是出于实现的原因,就是做了这样的设计。但这种设计却引发了很多令人困惑的问题。

假设我们使用32位版本内核,系统装有2G物理内存,下面所说的“内核的虚拟内存”是指内核前896M虚拟内存。

"内核将自己的虚拟内存连续映射到低端物理内存"到底会产生什么样的结果?是说低端那896M物理内存已被内核所占而不能另做它用?
昨天讨论内存的帖子里给出了否定答案,看起来这是个很老的问题了。

书上往往会还有这样的话语:内核只能使用最低端896M物理;超过896M的内存称之为“高端内存”,无法被内核直接使用。初学者读到这里,总觉得哪里不对劲,却又道不出个所以然来。

既然内核已将自己的虚拟内存映射了,内核页表里entries是怎样的呢?在entry中,我们当前感兴趣的有两项:映射地址与Present标志位。映射地址嘛,肯定安排好了。Present标志位是不是1呢?不妨认为是1。这样一来,从内核的页表上来看,前896M的物理内存的的确确被内核所“占用”,只要内核引用相应的虚拟地址,内核就会访问到相应的物理地址,不会发生任何意外。但是,如前面所说,进程也是可以使用这块内存的。如果某个进程的某个虚拟地址映射到了前896M中的某一段,那么内核与进程都可通过各自的页表访问到这块内存。这样会不会发生冲突呢?

描述页帧的数据结构是page结构体,一个页帧是否空闲正是取决于对应page结构体中的引用数。那么内核映射的那896M物理内存是否空闲呢?除了内核代码及静态数据所占的物理页外,其它的理应全是空闲状态。也就是说《内存管理子系统》可以把这些内存分配出去。昨天帖子里说的“被内核映射了不等于被内核使用了”就是这么回事。内核页表里的内容是说,前896M物理内存处于一种Ready to use的状态,然而没有被内核使用的内存,进程也可以使用。在896M内存中,内核不能使用“被进程使用的内存”,即内核不能引用相应的页表里的内容,即内核不能使用相应的虚拟地址。

内核怎么能保证不引用某段虚拟地址呢?换句话说,内核是怎么使用自己的虚拟地址的呢?她怎么知道哪一段的虚拟地址已经《被
自己使用了或者因为进程而不能使用》呢?总之,内核如何管理自己的虚拟地址呢?

先看内核如何管理进程的虚拟地址。

当进程需要内存时,内核首先会为进程分配一段虚拟地址,即所谓的Memory Region。由于进程虚拟地址的使用情况记录在vm_area_struct中,所有的vm_area_struct都按照顺序连接在一个链表上,因此寻找某大小的虚拟地址十分简单,扫描这个链表,碰到一块大于或等于[所申请内存大小]的连续地址,便用新的vm_area_struct记录下来,并插到链表的合适位置,这块虚拟地址便被标记为“已用”了。其实这就是操作系统理论里所讲的first fit。早期的Unix就是这样管理物理内存的,而这里用之管理进程的虚拟内存。内核为进程分配内存的步骤如下:
一、找到合适大小的虚拟地址段;
二、向{内存管理子系统}申请物理页帧;
三、在进程页表中建立两者的映射关系。

然而,内核为<自己>分配内存时,只有#第二步#。

没有第三步,是因为一开始的时候,内核页表已经做好了映射。那第一步呢?内核为什么没有像进程一样<<寻找合适大小的虚拟地址段>>这一步骤?

内核自己需要内存时,总是向Slab层申请(?)。需要创建新的数据结构,需要一个buffer时,Slab便为之分配一块连续的内存。内核不需要对这块内存做映射,因为最开始就映射好了。只要这块连续的物理内存在前896M之内,它本来就处于一种“预备被内核使用”的状态。从Slab里分出来后,它就“正式被内核使用”。那么,内核{申请内存时}得到[虚拟地址]是由什么决定的呢?内核没有“额外管理”虚拟内存,具体使用哪一块虚拟内存取决于Slab分配哪块物理内存。Slab分配哪块物理内存又取决了{内存管理子系统}。{内存管理子系统}={Buddy System}

结论是:Buddy System管理了内核的虚拟内存。

严格来说,Buddy System在管理前896M物理内存时随便把内核的虚拟内存也管理了,因为两者是严格映射的。对进程来说,分配虚拟内存与分配物理内存是分开的步骤;对于内核来说,分配了物理内存就等于分配了虚拟内存。内核为自己分配的内存究竟在虚拟内存的什么位置取决于分[配到的内存的页帧]在物理内存中的哪个位置。进程需要额外的结构体记录虚拟内存的使用情况;内核虚拟内存的使用情况就是前896M物理内存的使用情况。换句话说,一旦进程申请到了前896M物理内存中的某一块,就相当于侵占了内核的虚拟地址空间,就相当于内核的这段虚拟地址段不可使用。如果一块物理内存被Buddy System分给了内核,进程是没有机会再得到这块内存的,也就没有机会映射这块内存。如果一块物理内存被Buddy System分给了进程,虽然内核已经预先映射了这块内存,但永远得不到相应的虚拟地址,也自然引用不到相应的表项。这样就避免了两者间的冲突。当然,如果内核有BUG,指针使用不慎,引用了不该引用的虚拟地址,很容易破坏进程的内存。

这样一来,问题都解决了。前896M物理内存由内核与进程混用。但内核只能使用这896M物理内存(因为它的页表映射是固定的),而进程可以使用任何地方的物理内存(因为它的页表可以随意设置)。内核高128M留作其它用途,可以随意映射。内核不能直接使用的内存即“高端内存”。当内核的线性地址空间大于物理内存时,“高端”便不存在了。这种情况实际上有两种可能:一是内核线性地址空间太大,如使用64位系统;二是系统物理内存太小,如机器仅配有512M内存。两者都是{
内核线性地址空间大于物理内存}的结果。

管理进程的虚拟内存时,利用分页,可以把虚拟地址随意映射到任何物理地址,这正是我们印象中“分页机制的常规用法”。相反的,内核管理自己的虚拟内存时,利用分页,把“自己的虚拟内存固定到一块物理内存”,反倒限制内核能使用的内存在物理内存中的位置,正好与我们印象中{分页机制的常规用法}相悖。初学者看到这块内容时,总有种“说不清道不明”的不协调感,大概就是这个原因吧。

评分

参与人数 1可用积分 +30 收起 理由
godbach + 30 多谢分享

查看全部评分

论坛徽章:
0
发表于 2010-08-24 19:52 |显示全部楼层
深刻,帮顶,就是要这种真正懂了的人来讲,而不是瞎混。

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
发表于 2010-08-24 21:09 |显示全部楼层
写的不错.我们确实需要在框价和层次上把因果关系弄清楚,才不至于含糊不清.
还可以再继续讨论下同步的问题.
可以先分2步,一是MM的层次上再明确些
然后针对这些层次多对一的同步问题详细讨论.

论坛徽章:
0
发表于 2010-08-24 22:35 |显示全部楼层
呵呵。刚才始看还以为是问题呢。正好要解答。看到后来。原来是篇说明文章。正是我想说的。好文帮顶。兄台受累了。

论坛徽章:
0
发表于 2010-08-25 09:30 |显示全部楼层
如果不做嵌入式,研究高端内存貌似没啥用哈。因为现在都是64位的了。

论坛徽章:
0
发表于 2010-08-25 09:39 |显示全部楼层
LZ没研究高端内存吧。只是写了下32位LINUX的分页内存管理中的内核线性地址到物理地址的影射关系。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2011-04-15 14:35 |显示全部楼层
今天再次看了LZ这片文章,感觉获益匪浅

论坛徽章:
0
发表于 2011-04-16 00:41 |显示全部楼层
谢谢  收藏了

论坛徽章:
0
发表于 2011-04-18 14:27 |显示全部楼层
这篇老文又被挖出来了.......现在看起来写的真是罗嗦,当时其实连SLAB都没搞清楚,只是终于把那个896M搞懂了兴奋之余发了一贴.这进半年的时间,感觉自己又进步了不少,回想起大三下学期看LKD,完全不知所云啊.

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2011-04-18 14:57 |显示全部楼层
回复 9# tempname3
欢迎继续完善啊。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP