占用内存的程序会锁定系统

占用内存的程序会锁定系统

我遇到了以下问题:程序中有一个如下错误

int main() {
  for(;;) {
    char *p = (char*)std::malloc(1024);
    std::memset(p, 1, 1024);
  }
}

它会一直分配内存,直到我的系统开始将其他应用程序的页面交换给该程序,然后我就无法再在机器上执行任何操作了。我在使用不同的应用程序时多次遇到过这个问题(今天,是在 Firefox 中使用 Moonlight 2 Beta)。我认为问题是因为该程序导致其他程序的内存被交换出去,因此它可以使用更多的物理内存。

我自然而然地研究了 ulimit,发现了两个设置

-m最大驻留集大小
-v虚拟内存的大小

我读到第一个表示进程一次可以使用的总物理内存大小。对我来说,这似乎比总虚拟内存大小更合理,因为它可能是共享的,而且它可能根本不重要,因为它无论如何都会被交换出去。因此,.bashrc在查看了通常的常驻集大小后,我将以下内容添加到我的 中top,我发现对于通常的 Firefox 会话,常驻集大小最高可达 120MB 左右。

# limit usage to 256MB physical memory out of 1GB
ulimit -m 262144

但在运行上述测试代码后,它仍然导致我的系统崩溃,我不得不等待大约 5 分钟,直到终端识别出我^C按下的按键。通常,如果我在最初几秒钟内没有反应,在这种情况下,我只能按下重置按钮,我真的不喜欢这样 - 那么有人有解决这个问题的策略吗?为什么物理限制不起作用?在我看来,这样其他应用程序应该仍然有足够的物理内存来做出明智的反应。

答案1

您尝试过使用-v旗帜吗?

常驻工作集由交换前在 RAM 中保留为工作集的最大内存量定义。因此,它不会限制包含工作集交换部分的总内存量。该-v标志应该可以完成这项工作。

虚拟内存大小:内存相关限制中最有用的,因为它包括所有类型的内存,包括堆栈、堆和内存映射文件。尝试分配超过此限制的内存将失败,并出现内存不足错误。

令人惊讶的是,网络上深入描述这一点的资源并不容易找到!我在我的 Linux 机器上做了这个实验。

它因异常而停止

  ulimit -v 100000

并且没有使用-mflag。唯一让我吃惊的是例外:

segmentation fault

我本来期望如此out of memory

答案2

我认为 ulimit 实现在几乎所有操作系统上都很糟糕。我在 Linux 上使用 ulimit -S -v 已有六年了。六年!而且似乎有些内核不再支持它了。我有一台 Mac,OS X 10.6 不支持它。我也尝试过使用 -m。在我装有 Ubuntu 9.04 的旧台式机上,ulimit -S -v 运行正常。

确实,我正在寻找一个真正的解决方案。我只是无法相信苹果公司的人竟然允许他们的程序占用如此多的内存。

答案3

典型的内存泄漏。恐怕你需要修复有问题的应用程序,操作系统能做的不多。操作系统所能做的就是限制一个应用程序的内存,但随后有问题的应用程序会崩溃/出现段错误,并可能使操作系统或至少 xorg 也随之崩溃。

您可以 ld_preload 另一个版本的 malloc,并添加一个线程以在指定的秒数后释放它。但我怀疑它是否可行...

你需要这个教程: http://lattice.umiacs.umd.edu/files/functions_tr.pdf

相关内容