这本质上是“Linux:如何明确地取消所有可能的交换?“。
我想在运行一个我知道会大量使用系统内存的进程之前最大化可用的空闲内存量,并且我不希望它长时间暂停,直到操作系统意识到所有事情别的應該被換出。
另外,我知道很多程序都有内存,它们只在初始化时使用,然后再也不会触碰。
我怎样才能实现这一点?
我曾尝试过sysctl vm.swappiness=100
但几乎没有改变任何东西。
答案1
一旦内存用于其他目的,未使用的初始化代码将被释放。(它将由读取它的文件支持。)
Linux 上的内存分页机制设计精良,经过多年测试。您很少会想将任何进程换出内存。这会导致每次安排执行交换的进程时都产生大量分页活动。
如果您确实需要其他应用程序的内存,则说明您的内存太少了。您可以通过使用命令向其他程序发送STOP
信号来阻止它们执行kill
。请谨慎停止哪些程序,否则您可能会被锁定在系统之外。
如果您在启动进程时遇到长时间的暂停,请考虑使用sar
来确定瓶颈在哪里。您还可以使用来top
确定哪些进程正在被大量分页或交换。如果您的进程出现问题,请不要感到惊讶。
我运行过内存严重不足的服务器。要执行启动,必须限制一次启动的进程数。即使内存过剩,进程也几乎可以立即启动。
如果您真的想强制耗尽所有内存,您可以编写一个程序,分配所需的内存量,并在几个循环中不断写入分配的内存的每个页面。它将遇到您想要避免的所有问题。
答案2
您可能能够通过删除缓存(pagecache、dentry 和 inode)来实现您想要完成的任务。
echo 3 > /proc/sys/vm/drop_caches
将会清除所有。
更多信息请访问:Linux 内存管理 - 删除缓存
答案3
像这样:
cat > eatmyram.c <<EOF
void main() {
while (1) {
int* ip = malloc(1024*1024);
// force the allocated memory to be dirty
for (int i = 0; i < 256*1024; i++) ip[i] = i;
}
}
EOF
gcc eatmyram.c -o eatmyram && ./eatmyram
这将分配尽可能多的内存,然后死机。请注意,如果您的交换速度很慢,这将使您的系统无法使用。留意您的可用内存并按住 Ctrl-C!
现在,让我解释一下为什么我需要这个。我用早期终止失控的编译器调用,以防止它们导致我的系统无法使用,并且兹拉姆将未使用的内存保持在紧凑的大小。但如果出于某种原因我必须重新启用 zram 设备,Linux 将需要一段时间才能意识到它应该交换一些东西 - 并且我不能仅通过运行编译器来强制它交换一些东西,因为 1. earlyoom 将杀死编译器,并且 2. 如果我关闭 earlyoom,它只会释放一次运行所需的空间。重新打开 earlyoom,下一个稍大一点的编译器运行将再次终止。因此,我只是关闭 earlyoom,将eatmyram.c
所有未使用的内存强制放入 zswap,重新打开 earlyoom,然后继续我的一天。