提问人:Shahaboddin 提问时间:11/6/2023 最后编辑:Toby SpeightShahaboddin 更新时间:11/6/2023 访问量:56
内存拆分如何与 mmap() 和虚拟内存一起使用?
How does memory splitting work with mmap() and virtual memory?
问:
早期:
假设我们使用的是 32 位 Linux 操作系统,具有 4GB 的物理内存。
没有交换分区!
有一个内核,保留了 200MB 的不可分页内存,其他任何人都无法占用(整个陈述只是我的假设,您可以更正内核不这样做的值或声明)。
在时间 t₀ 有三个进程,并消耗 1GB 的物理内存。
p1
p2
p3
现在开始第 4 个进程,其中 4GB 内存和一个空文件,带有 !这个过程开始一个循环,将一些值写入这个 ed 数组的每个元素;喜欢这个:
mmap(2)
MAP_PRIVATE
PROT_WRITE
for
mmap
for(int i=0; i<4GB; i++) mmap_array[i] = i*i%255;
问题:
- 当进程写入了高达 2.8GB 的数据,要求写入下一个字节时,内核会停止其他 3 个进程,创建它们的映像,并且由于没有交换,将它们存储回 RAM 中;这又会消耗 1GB 的物理内存(因为它们在运行时有 1GB 的 RAM,所以图像大小相同)?
p4
- 如果上面的问题是肯定的,这是否意味着如果一个进程要求更多的内存,而这些内存由其他人持有,就会有上下文切换?
- 关于页面错误是如何工作的,从现在开始,由于这 1GB 无法释放,可用 RAM 仍然是 2.8GB,当询问数组的下一个元素时,内核是否会卸载第一页,然后加载新页面而不是卸载页面?
p4
- 如果第三个问题是肯定的(我对此表示怀疑),内核如何保留该新页面将使用其物理内存的未加载页面的值?(没有交换分区;它会强制磁盘交换空间吗?
- 如果是呢?卸载页面的值是否会通过备份文件传递,然后释放物理空间?
MAP_SHARED
- 当这样的进程(或RAM获得100%的其他情况)时,为什么系统挂起?是因为它需要额外的空间来恢复 和 的那些图像吗?或者那些将恢复到那 1GB 中,但一旦他们要求更多内存,他们就会冻结?
p4
p1
p2
p3
- 同样,如果 #6 是肯定的,并且使用的这 3 个进程不能或它们充当 #5?继续但速度很慢(当时只有一页 RAM)?
MAP_SHARED
SysRq
仍然有效;这是否意味着每个进程都会挂起,但由于内核保留了内存,所以它不会挂起?
所有这些问题都集中在一篇文章中的原因是,通过理解所有这些,我能够理解实际的问题,也就是我在标题中写的问题!
我只是对我想要得到答案的事情进行了编号,以避免评论人们写的答案。
答:
2赞
datenwolf
11/6/2023
#1
让我向您介绍“Linux 内存不足 (OOM) 杀手”https://rakeshjain-devops.medium.com/linux-out-of-memory-killer-31e477a45759
基本上,Linux 内核确实为每个进程都保持了“可牺牲性”的分数,如果它遇到无法完成内存分配的情况,它会按照分数的顺序牺牲进程,以腾出空间。
如果推送,尝试 mmap 写入的进程无法完成,因为无论内核多么努力地腾出空间,最终该进程都会发出 SIGBUS(总线错误、内存访问错误)信号。
评论
0赞
Shahaboddin
11/6/2023
很好的答案,感谢您的时间。所以请启发我,正如原始帖子的评论所说,如果启用了过度提交,当内存已满时,即使它试图像你所说的那样腾出空间,会发生什么?我的意思是,如果在没有内存和没有备份文件的情况下它被杀死,过度提交这个词意味着什么?它需要交换吗?MAP_PRIVATE
1赞
datenwolf
11/6/2023
它将接收到SIGBUS信号,这基本上意味着程序将被强制崩溃。SIGBUS 是 SIGSEGV 的表亲,但分段故障是由编程错误引起的,而总线错误是由编程器控制之外的故障引起的。
1赞
datenwolf
11/6/2023
@Shahaboddin:过度使用的原因是,许多内存分配器(即构建 malloc、new 等的东西)将在更大的预“分配”mmap MAP_PRIVATE区域池上运行,但在运行时通常只使用小得多的部分。在这样的工具中,可以从 VIRT 和 RES 统计数据之间的差异中看出。VIRT 是 mmap 编辑的内容,但 RES 是内存中实际使用的内容。过度使用可以更有效地利用资源。如果没有过量使用,将保留大量内存,但永远不会使用。htop
1赞
datenwolf
11/6/2023
@Shahaboddin:当然,在某些系统配置中,您(系统的所有者/管理员)从经验或理论推理中知道,请求的内存也将被使用。在这种情况下,建议禁用内存过量使用。如果没有内存过量使用,则如果请求的地址空间量无法容纳可用内存资源,则调用将失败(返回值)。mmap
MAP_FAILED
1赞
datenwolf
11/6/2023
@Shahaboddin大致是的。当然,细节要复杂一些;例如,同一页面合并(=重复数据删除),并且最近内存压缩也在循环中的某个地方。但就其要点而言......是的。
评论
mmap()
mmap()
MAP_PRIVATE