背景介绍
现在有35块内存,每块200M,均采用malloc分配。
在使用中,他们都被填入了10M~100M不等的数据,余下部分空闲。
然后我们将这35块内存中的有数据部分复制到一块1G的大内存中(已知有效数据总和不超过1G)。
伪代码如下
#define MAX_PER_BLOCK_MEM_SIZE (1024*1024*200)
#define MAX_TOTAL_BLOCK_MEM_SIZE (1024*1024*1024)
for ( i = 0; i < 35; i++)
mem[i] = malloc(MAX_PER_BLOCK_MEM_SIZE);
big_block = malloc(MAX_TOTAL_BLOCK_MEM_SIZE);
for ( i = 0; i < 35; i++)
put some data to mem[i];
len[i] = len(somedata);
for ( i = 0; i < 35; i++)
copyto(big_block, mem[i], len[i]);
这个段程序的执行结果是怎样的呢?由于总数据不足1G,按照一般机器的内存拷贝速度,预计总时间不超过1秒钟。但实际执行结果却让我费解,着1G不到的内存复制居然消耗了30秒!一般有两种情况会影响速度:
1、 Cache Miss
2、 Page Swap
鉴于速度下降如此厉害,Cache Miss的可能性不大。即使从Cache理论上分析,复制数据的过程与Cache命中率基本上无关---Cahce Read 的 Miss Rate必然接近100% ;对于Cache Write,Write-Back Cache可以一定程度上加速写内存的过程,但数据量一旦大大超过Cache Capacity,也会挂掉。 Write Through的Cache就不说了。所以应该是Page Swap造成的。
free查看空闲内存,约8G。 再算我申请的内存:35*0.2G + 1G = 8G 。居然是刚刚好……肯定是发生Page Swap了~!
系统空闲内存:
解决方法
将每块内存改小:
#define MAX_PER_BLOCK_MEM_SIZE (1024*1024*120)
重测,biu~~~秒杀。果然是发生换页了!
根据对操作系统内存分配机制的知识,这背后的机制却让我有些费解。
假设如下场景: malloc函数一次性分配了8G虚拟内存,而只实际只使用了其中的8G中的前面500M。
操作系统背后会做些什么呢?首先,为该进程分配映射8G空间所需要的页表,约占2M空间(按照PAGE_SIZE = 4KB算)。页表中填入什么呢?有两种选择:
立即分配(immediate allocation)方式: 只要有空闲物理内存页,就立即将这些空闲页分配给进程,页地址填入到页表中。
懒惰分配(lazy allocation)方式: 不管系统中有不有空闲物理页,页表中先什么都不填,仅仅标志NOT_PRESENT。当用户用虚拟地址访问到该页面时,将发生缺页中断。操作系统此时根据系统维护的状态可以知道该次访问是对页面的第一次访问,需要为其分配物理页面。now,操作系统向物理页面管理器发起物理页面申请,并将申请到的页地址填入到页表中,用户就可以继续对页面的访问了。
两种方式各自有何利弊呢?立即分配的方式的弊端由我上面的程序就已经可以看出来了。当用户喜欢预先申请大量内存,却不及时释放的时候,系统性能将受到严重影响。比如,A进程一次申请了8G内存,B进程如果想申请2G内存,则没有可用物理页了。只好将页表标记为NOT_PRESENT。一旦B进程访问这2G内存,将发生缺页中断。由于系统中没有可用物理内存了(A进程在占着茅坑不拉屎@@),操作系统换页机制将启动,当前某些物理页将被换入到磁盘中。这个过程相当耗时!
对于懒惰分配方式,上面的情况将不会出现,因为A进程分配的8G内存并没有实际分配,系统内还是有8G的空闲物理页。懒惰方式的缺点在于,缺页中断将会频繁发生!陷入内核的开销也是不容小觑的。举个例子:某个进程A,分配了1G内存,由于采用了懒惰分配方式,顺序访问这1G内存将会导致1G/4K=256K次缺页中断。假设每次中断处理时间需要1us,那么缺页造成的损失为1us * 256K = 256ms = 0.2s,在性能很重要的计算环境下,这个开销已经很大了。
解决方案
系统进行内存分配的时候,区别对待大内存分配和小内存分配。对于大内存分配采用懒惰分配方式,对于小内存,则一次性满足。在采用懒惰分配方式的时候,每次发生了缺页,可以一次分配几十到几百个页面给进程,这样可以有效避免懒惰分配方式中存在的缺页开销大的问题。
结论
莫非linux犯傻了?回头看看源码去~
Note:
这里“缺页中断”有两种语义,请注意区别:
1、传统意义的缺页中断。内核需要到磁盘上去读回所缺页。
2、物理页层次的缺页中断。此时实际上有足够的物理页面,只不过这些物理页面没有分配给进程而已。只有当发生物理层次的缺页中断时这些物理页才分配给进程。
分享到:
相关推荐
在现代社会,善待他人已经成为了人际交往中的重要原则。这一原则不仅仅体现在表面上的礼貌与客气,更深层次的是心灵之间的相互理解和宽容。在《善待他人的事例精选.doc》中,我们看到善待他人所蕴含的深刻意义,以及...
标题中的“善待生命[善待人生善待生命美文欣赏]”暗示这是一份关于生命哲学、人生观和价值观的文档集合,可能是由一系列文章或散文组成,旨在引导人们理解并珍视生活,培养积极的人生态度。由于标签是“教育”,我们...
在这样一个大背景下,一份名为《善待地球保护环境PPT教案.pptx》的课件,通过图文并茂的形式,系统地向我们展示了保护环境的重要性,并提出了具体的环保建议。 环境保护并非是一个全新的概念,但是如何在大众,特别...
《疫情下一定要善待你所在的单位》读后感.docx
在现代社会的快速发展中,人们面临着各种挑战和选择,其中最为重要的是学会如何善待生命。生命是有限的,每个人都有义务去尊重和珍惜。在探讨“善待生命”这一主题时,议论文成为我们表达观点、分析问题的重要文体。...
### 《疫情下,一定要善待你所在的单位》心得体会关键知识点解析 #### 一、学会感恩:企业与员工之间的共生关系 1. **企业的角色**:企业不仅是员工获取收入的平台,更是员工成长和发展的重要基石。它为员工提供了...
在我们的生活哲学中,“善待自己”是一个常被提及的话题,它不仅仅关乎个人的自我感觉,更是一种深层次的生活态度和行为准则。中考满分作文“善待自己”通过对善待自己含义的深刻阐释,为我们提供了一个全新的视角去...
本文旨在通过小学生的眼光,探讨如何善待我们的地球,以及这一行为与我们每个人切身利益的紧密联系。 “白色垃圾”是塑料污染的代名词,它描述的是一次性塑料制品如塑料袋、塑料瓶等不易降解的废弃物。这些物品被...
民本与善待
善待自己,善待生命,防止踩踏,安全第一.docx
在探讨人际关系的复杂性中,【善待他人】始终是其中的金科玉律,它不仅仅是一种行为准则,更是一种深入骨髓的哲学思考。在日常生活或历史长河中,我们都能发现众多的事例,用以说明善待他人的重要性。这不仅是对他人...
因此,“善待他人”不仅是一种道德规范,更是构建和谐社会和个人成功的关键。善待他人意味着尊重、理解和包容,它能帮助我们更好地融入群体,赢得友谊、信任、谅解和支持。 让我们首先来理解“善待他人”的重要性。...
【标题】:善待自己读后感 【描述】:本文是对一篇名为《善待自己》的文章的个人感悟,作者反思了过去过于关注他人而忽视自我,决定开始善待自己,找到生活的乐趣和价值。 【标签】:自我关爱,生活态度,个人成长...
高健善待节外生枝.doc
《善待他人》这篇文章深刻揭示了人际关系中的重要原则——善待他人。善待他人不仅是对他人的尊重和关爱,更是自我成长和完善的过程。在这个多元化的世界里,我们与各种各样的人接触,理解和宽容成为了建立良好人际...
2. 善待生命:文章反复提及善待生命的重要性,无论是对待自然界的生命,如植物和动物,还是对待人类自身,都需要以尊重和爱护的态度去面对。这不仅是对他人的责任,也是对自己的珍视。 3. 生命的脆弱与坚强:文中...
【标题】:“初中语文经典美文善待生命”所揭示的知识点主要集中在对生命的思考、理解和尊重上,它引导我们去关注和珍视生活中的每一刻。 【描述】:“初中语文经典美文善待生命”这个主题,暗示了文章可能通过一...
《请善待你所在单位》是一篇关于职场态度和工作价值观的文章,它通过深入浅出的文字,传递了对待工作和单位的正确心态。文章分为几个核心部分,分别讲述了善待单位的重要性和如何在实际工作中体现这种善待。 首先,...
《善待自己》这篇文章带给读者的是一份深刻的反思和启示,它强调了个体自我价值的重要性,提醒我们在忙碌的生活中不应忽视自身的感受和需求。善待自己,并非是一种自私的行为,而是对自己的一种关爱和尊重,这有助于...
1. **时间管理**:文章中提到,十二月是一年中的最后一个月,提醒我们要善待时光,合理安排时间。对于个人而言,时间管理是提高效率、实现目标的关键。我们应该审视年初设定的计划,看看哪些已经完成,哪些需要在...