免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 瀚海书香

linux内存管理讨论——欢迎大家围观! [复制链接]

论坛徽章:
4
CU大牛徽章
日期:2013-03-13 15:29:07CU大牛徽章
日期:2013-03-13 15:29:49CU大牛徽章
日期:2013-03-13 15:30:192015年迎新春徽章
日期:2015-03-04 09:57:09
发表于 2012-03-28 17:15 |显示全部楼层
当年研究操作系统原理的时候研究了下,现在好多年了……

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
发表于 2012-03-28 17:53 |显示全部楼层
回复 1# 瀚海书香
这里说一个关于内存的实际的应用,用户态进程的虚拟地址如何转换成物理地址?

区分一个进程,我们都知道最简单就是进程的pid。我们就从(pid,virtualaddress)来看看如何将一个进程的虚拟地址转换为物理地址phyaddress。
首先根据pid我们可以得到这个进程的task_struct,进而通过task_struct得到mm,通过mm得到pgd。
好了,现在我们有pgd和virtualaddress.
通过pgd和virtualaddress我们可以得到页表pte.
有了pte和virtualaddress,我们就可以计算物理地址了
phyaddress=(pte_val(pte)&PAGE_MASK)|(virtualladdress&~PAGE_MASK)
物理地址既然出来了,访问这个地址的值就比较简单了,只需要将物理地址转换为内核线性地址就行。
*phyaddress=*((char *)phyaddress+PAGE_OFFSET)

   

论坛徽章:
0
发表于 2012-03-28 18:21 |显示全部楼层
如果把内存管理的范围扩大点,如何访问和管理设备的地址空间呢, 这个领域有没有深入学习的同学来分享知识? 比如说,我现在开发了一块基于PowerPC  的平台, 其物理地址已经被硬件固化。 如何在Linux 系统里,使用什么机制来访问这些物理地址,
Unit computer memory configuration
Resource                             Address range                      Size        Port width             Chip Select
Main memory                      0x0000_0000 – 0x1FFF_FFFF        512 MB           64             M1_MCS0
Application FLASH (NAND)        0x4000_0000 – 0x4000_1FFF        8KB           8             HP_LCS2#
PCI Express Memory Window        0x5000_0000 – 0x5FFF_FFFF        256 MB           n/a             n/a
SRIO Window                      0x6000_0000 – 0x9FFF_FFFF        1 GB           n/a             n/a
Memory mapped registers        0xC000_0000 – 0xC000_000F        16 B           16             HP_LCS3#
CCSRBAR                                    0xE000_0000 – 0xE00F_FFFF        1MB               
Redundant boot FLASH        0xF000_0000 – 0xF7FF_FFFF        128 MB           16             Flash1_CS#
Boot FLASH                      0xF800_0000 – 0xFFFF_FFFF        128 MB           16             Flash0_CS#

论坛徽章:
0
发表于 2012-03-28 18:34 |显示全部楼层
先顶下!

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
发表于 2012-03-28 19:43 |显示全部楼层
内存管理一节我也非常感兴趣。瀚海书香版主说的都是x86架构上的内存管理,各种的架构对内存的管理很大的不一样。像mips的内存管理就和X86有很大的不一样。内存管理这一章不深入理解下架构上的实现,总会有一些说不清道不明的感觉。

论坛徽章:
4
CU大牛徽章
日期:2013-03-13 15:29:07CU大牛徽章
日期:2013-03-13 15:29:49CU大牛徽章
日期:2013-03-13 15:30:192015年迎新春徽章
日期:2015-03-04 09:57:09
发表于 2012-03-28 21:15 |显示全部楼层
本帖最后由 dooros 于 2012-03-28 21:16 编辑

当年看汤子瀛等主编的《计算机操作系统(第二版)》中笔记下的一些疑问,关于内存的,原理性的,不涉及代码实现,上次问了,这次继续。

一、Page 116 4.3.2 地址变换机构
2.具有快表的地址变换机构
快表用以存放当前访问的那些页表项。
问题:在单处理机系统中,是不是每当进程阻塞、挂起、结束都要清除一次快表,即:快表只保留当前进程的页表项?
当前访问的理解?比如现在进程使用50个页,则快表中只保存50个页的信息,一段时间后,进程使用20个页,则快表立即清除其余30个页的信息,只保留20个页的信息。这样理解对否?
如果在多处理机系统中,进程并发执行,则快表同时保存多个进程的页表项(页号与物理块号的对应信息),如果快表中多个进程的页号相同,岂不乱套?是不是多处理机系统中有多个快表?
二、Page 114 4.3.1 页面与页表
问题:在分页存储管理中是所有的进程的页面大小都相等,还是不同进程有不同的页面大小?
分页存储管理中是不是把所有内存都划分为大小相等的物理块?页表是不是也存储在这样的物理块中?还是页表独立分配空间?
三、Page 119 4.3.3 两级和多级页表
2 多级页表
倒数第二段最后一句:
这样的结果显然是不能令人接受的,因此必须采用多级页表,将外层页表再进行分页,也是将各分页离散地装入到不相邻的物理块中,再利用第二级的外层页表来映射它们之间的关系。
问题:这里是不是只能使用将部分页表调入内存这种方法?
四、Page 159 5.3.4缓冲池
第一段的最后一句话:为了提高缓冲区的利用率,目前广泛流行公用缓冲池;在池中设置了多个可供若干个进程共享的缓冲区。
问题:是不是整个缓冲池有一个空缓冲队列emq,而对应每个进程均需要一个输入队列inq和一个输出队列outq?如果整个缓冲区仅有一个输入队列inq 和一个输出队列outq,那么,在进程共享使用时,岂不是无法确定摘取的是否是自己需要的缓冲区?另外,队列的数据结构也不允许随机摘取。

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
发表于 2012-03-28 21:18 |显示全部楼层
这个要参加啊。

论坛徽章:
0
发表于 2012-03-28 21:24 |显示全部楼层
我讲一讲自己在学习过程中遇到的不解之处,及各个概念的高度总结。好吧,其实是前几天发现包破了。。。。

1.内核是否有独立的地址空间。
X86上的Linux内核没有独立的地址空间。作为对比,DEC-11上的Unix V6内核有独立的地址空间,一旦进入内核态,页表自动切换。这样操纵用户态时就可跳出三界外。现在几乎没有操作系统这样做。根据某部FreeBSD著作所讲,内核态常做的一件事就是从、向用户空间搬、传数据。内核与用户态进程不在一个地址空间,则需要额外的指令在两个地址空间里传数据。

但这确实是一种设计,有其历史渊源。



2.内核态内存的映射。
X86上Linux内核之内核态虚拟地址,大部分固定地与低端物理内存一一映射。这样做的理由,一来是想更容易地访问物理内存,二来方便使用动态申请到的内存。DEC-11上的Unix V6内核就算有自己独立的地址空间,其大部分映射也是与物理内存一一对应的---在内核眼中,大部分虚拟地址与物理地址都是一样。

Linux上则仅仅有个差值。



3.896M与高端内存
X86上Linux内核与进程共用地址空间,另外,内核所有的地址空间被设计成与内存固定映射。结果是:内核拥有的地址空间很小(因为用户态占了大部分);能灵活使用的虚拟地址不多(因为大部分要与物理内存做一一对应的关联)。于是,内核能使用物理内存的大小被其狭小的虚拟地址空间所限制了。即便有再多的物理内存,内核已没有多余的虚拟地址与之映射,从而无法访问。

所以,896M用于与物理内存建立一一对应关系,剩余的虚拟地址空间,分时映射没能被896M覆盖到的物理内存,这部分物理内存就是高端内存。内核自己申请动态内存时,通常只在这896M以内申请,免得为了使用还得建立映射关系。其内部大量cache都在这一区域内,所以这块内存比较宝贵。用户虚拟地址空间可以随意设置,给用户态分配内存时,优先从高端内存取(如果有的话)。


4.映射与使用
内核映射了低端896M物理内存,大部分动态内存都从这里获得。但这并不是说这些内存就属于内核了,用户态不能用了。动态内存的使用要由mm子系统来协调,基本原理就是:分出去的内存不能再被分出去;收回来的内存可以被再分出去。动态内存的归属,最终由mm子系统来调度,申请到了再使用,这样才能保证秩序。分给用户态了,先建立映射,用户程序就可安心用了,即使内核可以直接访问这块内存,只要没有BUG,它都是很安全的。分给内核态了,直接使用即可--映射早已建立。

如果896M内的物理内存分给用户态,内核自然不能使用。而且与之关联的虚拟地址段也不能另作他用。可惜了。


5.虚拟地址空间
虚拟地址空间也是资源。于用户态而言,典型的例子是在扩展地址空间之时:需要找到一块没用的地址空间。必需得记录哪些地址空间被用了,哪些没有被用。分配虚拟地址空间与分配物理内存其实是一样的道理,只不过物理内存是全局的,需要用更精妙的算法来分配。Linux虚拟地址空间似使用first fit----沿途看看有没有合适的地址段,第一个找到的就是。其实Unix V6就是这么分配物理内存的。

有数据结构描述用户态地址空间段,内核怎么管理自己的虚拟地址空间呢?是什么决定其动态申请内存时获得内存的位置?由于大部分虚拟地址空间都与物理内存一一对应,两者完全可以合二为一:管理虚拟内存段就是管理物理内存。申请的虚拟地址的情况取决于申请到物理内存的情况。

高端分时复用的那一块虚拟地址空间,面临的需求和解决方案,与用户态一样。


6.Buddy System
管理物理内存最基本的要求:判断一块内存单位是否被使。只记录这一个信息的话,一个bit足矣。于是可以用一个bitmap描述当前物理内存的使用情况。实际上,一块内存单位的属性远不止是否被使用,其复杂程序需要用一个结构体来描述。下一步是考虑分配内存的策略。Buddy System就是策略的一种。其原理,至少从表面上看起来,并不复杂。它主要为了解决外部碎片:系统中有足够量的内存满足需要,但是这些内存散乱在各地,无法作为整体来使用。


7. Slab
现代操作系统通常以页作为物理内存单位,这是分配与回收的最小单位。分配一页给一页你,分配几byte还是得给一页你。如果分出去的内存大部分没有被使用,那就太可惜了。一个频繁分配小内存的代码段,可能会先分配几页,然后自己内部管理这些内存,通过某种方法一点点满足小内存分配的需要。slab就是提取出来,专门做这种事的代码。它并不在乎底层用的是何种内存分配方式,它只在乎地层提供的分配与释放的接口,然后向上层提供分配小块内存的接口。之前向底层要的物理内快完了,它会负责再要一点;之前从底层拿的内存多了用不完,它会择时还回去。它默默地做着这些脏活,留给上层一个功能简单明了的接口。


8.mmap与虚拟地址空间
以前看APUE,以为mmap是个trick十足的系统调用。后来才明白,如果不理解内核的cache系统,mmap的作用很难理解。在内核里,带mmap字样的函数更让人觉得trick:它们用来分配用户态的虚拟地址空间。这似乎偏离了mmap的初始意图。

初始的时候,虚拟地址空间的样子由可执行文件,比如ELF,来决定。如果地址空间与文件映射,就叫有名映射(好吧,好像没有这种叫法);如果纯粹扩展一段地址空间,比如从用户态上去理解malloc的语义,就叫匿名映射,虽然看不出来整个过程哪里跟映射有关了。于是,用户态的地址空间就这么一点一点被有名映射,无名映射筑起来了。


评分

参与人数 1可用积分 +10 收起 理由
瀚海书香 + 10 赞一个!

查看全部评分

论坛徽章:
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
发表于 2012-03-28 21:42 |显示全部楼层
回复 1# 瀚海书香
好活动,强烈支持。

   

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2012-03-28 23:39 |显示全部楼层
本帖最后由 塑料袋 于 2012-03-28 23:48 编辑

占位,计划谈page compaction及migration的提出目的,实现手段。

目的:
1) NUMA结构,进程迁移,则进程的内存页面若也迁移至目标CPU,则对这个进程来说,访存最快。
2) 内存热插拔
3) huge page
4) buddy造成的的内存碎片化:buddy有求必应,一律从满足要求大小的,最小的连续内存片段分配,但是无视分配的性质。考虑场景如下,1234共4个页:
   a) slab临时性的分走[1],随时可能shrink cache收回,此时剩余[2],[34]
     b) 某driver长期性的分走[2],这页不可能收回,此时剩余[34]
     c) slab临时性的分走[3],随时可能shrink cache收回,此时剩余[4]
     d) 某driver长期性的分走[4],这页不可能收回,此时无剩余
   e) slab释放了[1],此时剩余[1]
     f) slab释放了[3],此时剩余[1],[3]
由此导致碎片化。但若将内存按照分配的性质分类,[12]归于movable,临时性的分配从这里分;[34]归于unmovable,长期性占用从这里分,则不会产生这种情况。



将内存按照分配的性质来来划分成几部分,需要一个划分的依据。以前的版本中分了三部分:MOVABLE,RECLAIMABLE ,UNMOVABLE 。movable最可能被随时释放,unmovable最不可能被释放。buddy中的每个order,都被分成这3部分。
这三部分中,那一部分到底应涵盖多少内存,不应设置成死的,而应根据分配的情况来动态调整。即:
unmovable不够,则先自reclaimable借,后自movable借。
movable不够,则先自reclaimable借,后自unmovable借。
原则为尽量少改动内存的易释放性,从最接近自己的那类中来借。

当本order管理的内存中借也借不着时,那只好在斥逐于更高的order,整个拿来一块,将这一块分成小块,除了分配出去的那小块外,其他的尽量不更改易释放性。


MOVABLE中的内存是重头戏,除了只分配给那些临时性的请求外,对这些内存,还可以进行compaction及migration。
compaction发生于内存不足时,基本上是个和page reclaim并列的逻辑。自头至尾释放zone内的页,这些页都在lru中,且页与页之间可能有缝隙,即碎片化;自尾至头分配zone内的页,这些页都属于movable,且分配的原则为见缝插针,中间不产生缝隙。将被释放页的内容复制到新分配的页,同时依据被释放页的反向映射,修改所有引用被释放页的pte。

占位待续

评分

参与人数 1可用积分 +10 信誉积分 +2 收起 理由
瀚海书香 + 10 + 2 很给力!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP