交换出属于进程的内存页面是否会暂停或停止进程本身?

交换出属于进程的内存页面是否会暂停或停止进程本身?

我有一个实时网络应用程序,它对任何类型的“阻塞”都极其敏感,并且需要在大多数时间具有极高的响应速度和完美的延迟。

不幸的是,应用程序(多线程)本身非常消耗内存,它需要大约 6GB 的 RAM。

该系统有 8GB RAM 和 2GB 交换空间。我观察到一些性能问题,与交换事件相关的应用程序延迟增加(每 15 秒使用 grafana 和 node_exporter 监控操作系统),恰好在发生严重延迟的同时,操作系统正在交换一些页面(同时仍有 2GB 可用空间)记忆)。

我非常了解 Linux 内核 VM 子系统(我读过 Mel Gorman 的《了解 Linux® 虚拟内存管理器》一书),因此我将其与操作系统主动换出非活动页面以获得更多的 FS 缓存/缓冲区空间联系起来,如果它不会严重影响该应用程序的延迟,我不会介意。

我设置是vm.swappiness = 0为了让内核在达到低内存水位线时仅使用交换作为最后的手段,但无济于事 - 它不断交换出大约大约很小的内存块。每 30 分钟一次,严重影响了应用程序的延迟。

唯一有帮助的是完全禁用交换 - 自从我这样做以来,延迟问题就再也没有发生过。但这也是一个问题,因为如果发生一些不幸的情况,当应用程序暂时需要更多内存接近总使用量 8GB 时,OOM Killer 现在会杀死它,而不是交换出部分非活动页面,这会更糟场景比瘫痪的延迟。

所以我有两个问题:

  • 为什么这些小的换出事件会严重影响应用程序的延迟?我的理解是,交换器无论如何都会驱逐不活动的内存页面 - 当交换器移动其内存时,即使它不尝试访问不在 RAM 中或正在移动的页面,进程是否会被冻结?
  • 有没有办法强制内核仅在必要时进行交换?例如。 - 当 RAM > 1GB 仍然可用时不要交换?

答案1

不幸的是,无法回答内核实际上做了什么。不过,有些事情可能会对您的具体问题有所帮助:

  • 获取更多内存
  • 使用更少的 RAM,优化
  • 在 ZRAM 上交换而不是交换到磁盘,据说这可以快一个数量级。基本上,当你换出一个页面时,它只是将其压缩在内存中,而不是将其写入磁盘 - 即使有压缩算法的开销,这也会快得多。
  • 如果您尚未使用它,请尝试使用 RT-linux 内核补丁集。整个“实时Linux”项目的重点是运行应用程序,如果错过延迟目标就意味着有人死亡,所以我假设你不会在那里看到这种灾难性的延迟问题。至少我希望你不会,那会很糟糕。大多数发行版都有可用的 rt 内核。
  • LE9 内核补丁也可能有一定的相关性,特别是它们在内存不足的情况下处理交换行为。 Linux 内核将包含可执行代码/库的页面视为主要交换材料,它会首先将它们交换出来。然后你的程序开始运行该代码,遇到页面错误,在换入页面时冻结,然后继续。据我了解,LE9 补丁可以保护您的可执行页面免于急切地交换,以防止在内存不足时破坏这些页面,以便系统能够优雅地处理它而不是冻结。

虽然我不知道交换时会发生什么出去,每当交换时你的进程肯定会停止,这就是处理页面错误的方式。您尝试访问某些内存,该页面未加载,内核停止所有操作,加载该页面,然后再次启动您的程序,希望当您请求时该内存不存在。我假设如果某些东西被换出,它最终也可能会被换回来,然后它肯定会停止你的进程。这可能就是正在发生的事情。

答案2

不幸的是,应用程序(多线程)本身非常消耗内存,它需要大约 6GB 的 RAM。
(...)
系统有 8GB RAM

您的系统内存不足;我认为解决您问题的唯一方法是添加一些内存。

请记住,从内存中换出的页面将写入磁盘,这提供了慢得多读/写访问权限高于 RAM。这一定是您的应用程序速度变慢的原因。

据观察,即使 swappiness 设置为 0,Linux 也会进行交换。相关问题:Linux 是否执行“机会主义交换”,还是一个神话?

相关内容