我正在尝试模拟内存耗尽。所以这就是我的想法:
- 关闭提交。
- 减少可用堆,以便更快地发生内存耗尽。
- 运行被测程序。
我的问题是 2:是否有减少内核将分配的堆大小的技巧?我可能可以编写另一个分配大量 RAM 的程序,但可能有更聪明的方法?
ulimit
您可以使用系统调用删除最大进程内存大小。该命令可从 shell 获得。有问题的选项是-v
(最大内存大小),例如,要将进程限制为最大 2GB,您可以这样做:
ulimit -v 2097152
然后你从那个 shell 启动进程。
如果您使用-H
ulimit 选项,那么它会设置一个硬限制,一旦设置就无法增加(root 可以增加限制)。
如果你想从程序中控制,你可以使用setrlimit
系统调用,方式如下:
#include <sys/types.h>
#include <sys/resource.h>
struct rlimit the_limit = { 2097152 * 1024, RLIM_INFINITY };
if (-1 == setrlimit(RLIMIT_AS, &the_limit)) {
perror("setrlimit failed");
}
这将软限制设置为2GB
,您可以通过更改RLIM_INFINITY
值来设置硬限制。请注意,如果您是 root,则只能增加硬限制。
此限制适用于可用于进程的内存总量,而不仅仅是可用作堆的内存。
可以使用该-d
选项限制堆内存。setrlimit
调用的等效名称是RLIMIT_DATA
。此限制仅适用于内存分配 - 例如 malloc、mmap、静态数据。
如果使用ulimit -d
,您可以限制用于堆分配(以及全局/静态变量)的数据段大小。
要模拟内存耗尽,您还可以使用 mmap 来映射大内存段并确保将它们“锁定”在内存中。请参阅 mmap 手册页,了解如何将页面锁定在内存中。这样它们就不会被交换,并且可用内存将减少。
如果对大型连续 mmap 段的请求失败,您可能需要请求几个小段(例如 256KB)。此外,如果你想一路走下去,你可能需要让你的 mmap 进程对 Linux“OOM 杀手”免疫(通过将 OOM prio 设置为 -17)。否则,当 Linux 发现系统的可用内存过低时,它可能会选择并杀死正在调用 mmap 的进程,以释放内存。