内存拆分如何与 mmap() 和虚拟内存一起使用?

How does memory splitting work with mmap() and virtual memory?

提问人:Shahaboddin 提问时间:11/6/2023 最后编辑:Toby SpeightShahaboddin 更新时间:11/6/2023 访问量:56

问:

早期:

  1. 假设我们使用的是 32 位 Linux 操作系统,具有 4GB 的物理内存。

  2. 没有交换分区!

  3. 有一个内核,保留了 200MB 的不可分页内存,其他任何人都无法占用(整个陈述只是我的假设,您可以更正内核不这样做的值或声明)。

  4. 在时间 t₀ 有三个进程,并消耗 1GB 的物理内存。p1p2p3

  5. 现在开始第 4 个进程,其中 4GB 内存和一个空文件,带有 !这个过程开始一个循环,将一些值写入这个 ed 数组的每个元素;喜欢这个:mmap(2)MAP_PRIVATEPROT_WRITEformmap

    for(int i=0; i<4GB; i++)
        mmap_array[i] = i*i%255;
    

问题:

  1. 当进程写入了高达 2.8GB 的数据,要求写入下一个字节时,内核会停止其他 3 个进程,创建它们的映像,并且由于没有交换,将它们存储回 RAM 中;这又会消耗 1GB 的物理内存(因为它们在运行时有 1GB 的 RAM,所以图像大小相同)?p4
  2. 如果上面的问题是肯定的,这是否意味着如果一个进程要求更多的内存,而这些内存由其他人持有,就会有上下文切换?
  3. 关于页面错误是如何工作的,从现在开始,由于这 1GB 无法释放,可用 RAM 仍然是 2.8GB,当询问数组的下一个元素时,内核是否会卸载第一页,然后加载新页面而不是卸载页面?p4
  4. 如果第三个问题是肯定的(我对此表示怀疑),内核如何保留该新页面将使用其物理内存的未加载页面的值?(没有交换分区;它会强制磁盘交换空间吗?
  5. 如果是呢?卸载页面的值是否会通过备份文件传递,然后释放物理空间?MAP_SHARED
  6. 当这样的进程(或RAM获得100%的其他情况)时,为什么系统挂起?是因为它需要额外的空间来恢复 和 的那些图像吗?或者那些将恢复到那 1GB 中,但一旦他们要求更多内存,他们就会冻结?p4p1p2p3
  7. 同样,如果 #6 是肯定的,并且使用的这 3 个进程不能或它们充当 #5?继续但速度很慢(当时只有一页 RAM)?MAP_SHARED
  8. SysRq仍然有效;这是否意味着每个进程都会挂起,但由于内核保留了内存,所以它不会挂起?

所有这些问题都集中在一篇文章中的原因是,通过理解所有这些,我能够理解实际的问题,也就是我在标题中写的问题!

我只是对我想要得到答案的事情进行了编号,以避免评论人们写的答案。

Linux 内存 linux-kernel mmap virtual-memory

评论

1赞 Toby Speight 11/6/2023
对于这个问题的任何答案,都有很多“这取决于”。很大程度上取决于是否启用了内存过量使用,在这种情况下,调用可能会成功,并且进程稍后会被内存不足处理程序终止。实际上,如果一个 32 位进程要求 4GB,实际上会失败,因为这比它所能处理的内存多,所以我们甚至不会达到这一点。mmap()mmap()
0赞 Shahaboddin 11/6/2023
@TobySpeight 谢谢你的话;好吧,我编辑问题并使其成为 3.9 GB?至于过度提交的情况(如果我理解正确的话),你写的实际上是一个答案。那么,如果启用了过度使用,它会怎么做?即使没有空间也要求下一页,那么因为没有空间来存储未加载的页面,并且过度提交新页面,它被杀死了?过度提交是否意味着它不应该卸载任何页面?为什么它会因为低内存而被杀死?MAP_PRIVATE

答:

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区域池上运行,但在运行时通常只使用小得多的部分。在这样的工具中,可以从 VIRTRES 统计数据之间的差异中看出。VIRT 是 mmap 编辑的内容,但 RES 是内存中实际使用的内容。过度使用可以更有效地利用资源。如果没有过量使用,将保留大量内存,但永远不会使用。htop
1赞 datenwolf 11/6/2023
@Shahaboddin:当然,在某些系统配置中,您(系统的所有者/管理员)从经验或理论推理中知道,请求的内存也将被使用。在这种情况下,建议禁用内存过量使用。如果没有内存过量使用,则如果请求的地址空间量无法容纳可用内存资源,则调用将失败(返回值)。mmapMAP_FAILED
1赞 datenwolf 11/6/2023
@Shahaboddin大致是的。当然,细节要复杂一些;例如,同一页面合并(=重复数据删除),并且最近内存压缩也在循环中的某个地方。但就其要点而言......是的。