9

我试图用来setrlimit限制我在 Linux 系统上的内存使用,以阻止我的进程使机器崩溃(我的代码使高性能集群上的节点崩溃,因为一个错误导致内存消耗超过 100 GiB )。我似乎找不到要传递给的正确资源setrlimit;我认为它应该是常驻的,不能用 setrlimit 限制,但是我对常驻,堆,堆栈感到困惑。在下面的代码中;如果我只取消注释,即使该数组应该只有 80 MB RLIMIT_AS,代码也会失败。如果我只取消注释,或两个数组都成功分配,即使总内存使用量为 2 GB 或所需最大值的两倍。MemoryErrornumpy.ones(shape=(1000, 1000, 10), dtype="f8")RLIMIT_DATARLIMIT_RSSRLIMIT_STACK

我想让我的程序在尝试分配太多 RAM 时立即失败(无论如何)。为什么没有RLIMIT_DATA,RLIMIT_RSS和做我的意思,传递给的正确资源是RLIMIT_STACK什么?RLIMIT_ASsetrlimit

$ cat mwe.py 
#!/usr/bin/env python3.5

import resource
import numpy

#rsrc = resource.RLIMIT_AS
#rsrc = resource.RLIMIT_DATA
#rsrc = resource.RLIMIT_RSS
#rsrc = resource.RLIMIT_STACK

soft, hard = resource.getrlimit(rsrc)
print("Limit starts as:", soft, hard)

resource.setrlimit(rsrc, (1e9, 1e9))

soft, hard = resource.getrlimit(rsrc)
print("Limit is now:", soft, hard)
print("Allocating 80 KB, should certainly work")
M1 = numpy.arange(100*100, dtype="u8")

print("Allocating 80 MB, should work")
M2 = numpy.arange(1000*1000*10, dtype="u8")

print("Allocating 2 GB, should fail")
M3 = numpy.arange(1000*1000*250, dtype="u8")

input("Still here…")

RLIMIT_AS未注释行的输出:

$ ./mwe.py 
Limit starts as: -1 -1
Limit is now: 1000000000 -1
Allocating 80 KB, should certainly work
Allocating 80 MB, should work
Traceback (most recent call last):
  File "./mwe.py", line 22, in <module>
    M2 = numpy.arange(1000*1000*10, dtype="u8")
MemoryError

与任何其他未注释的运行时的输出:

$ ./mwe.py 
Limit starts as: -1 -1
Limit is now: 1000000000 -1
Allocating 80 KB, should certainly work
Allocating 80 MB, should work
Allocating 2 GB, should fail
Still here…

在最后一行,top报告我的进程正在使用 379 GB VIRT、2.0 GB RES。


系统详情:

$ uname -a
Linux host.somewhere.ac.uk 2.6.32-573.3.1.el6.x86_64 #1 SMP Mon Aug 10 09:44:54 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 6.7 (Santiago)

$ free -h
             total       used       free     shared    buffers     cached
Mem:          2.0T       1.9T        37G       1.6G       3.4G       1.8T
-/+ buffers/cache:        88G       1.9T 
Swap:         464G       4.8M       464G 

$ python3.5 --version
Python 3.5.0

$ python3.5 -c "import numpy; print(numpy.__version__)"
1.11.1
4

1 回答 1

1

唉,你的问题我没有答案。但我希望以下内容可能会有所帮助:

  • 您的脚本在我的系统上按预期工作。请分享您的确切规格,Linux 发行版、内核甚至 numpy 可能存在已知问题...
  • 你应该没问题RLIMIT_AS。正如这里所解释的,这应该限制进程使用的整个虚拟内存。而虚拟内存包括所有:交换内存、共享库、代码和数据。更多细节在这里
  • 您可以在脚本中添加以下函数(从此答案中采用),以随时检查实际的虚拟内存使用情况:

    def peak_virtual_memory_mb():
        with open('/proc/self/status') as f:
            status = f.readlines()
            vmpeak = next(s for s in status if s.startswith("VmPeak:"))
            return vmpeak
    
  • 一般建议,禁用交换内存。根据我使用高性能服务器的经验,它弊大于利。
于 2016-09-29T08:46:58.947 回答