python - 如何使用 `setrlimit` 来限制内存使用? RLIMIT_AS 杀得太快; RLIMIT_DATA, RLIMIT_RSS, RLIMIT_STACK 根本不杀死

标签 python numpy memory setrlimit

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

我想让我的程序在尝试分配过多 RAM 时立即失败(无论如何)。为什么 RLIMIT_DATARLIMIT_RSSRLIMIT_STACKRLIMIT_AS 都不符合我的意思,什么是正确的资源传递给 setrlimit?

$ 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

最佳答案

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

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

    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
    
  • 一般建议,禁用交换内存。根据我使用高性能服务器的经验,它弊大于利。

关于python - 如何使用 `setrlimit` 来限制内存使用? RLIMIT_AS 杀得太快; RLIMIT_DATA, RLIMIT_RSS, RLIMIT_STACK 根本不杀死,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39755928/

相关文章:

python - 一次对两个元素进行分组

python - 将 Python NumPy 数组插入 PostgreSQL 数据库的最佳方法

java - OpenHFT Chronicle Map 内存分配和限制

c - 需要更多这方面的信息!中止(核心转储)

python - 消息不适合 sklearn k-means 收敛实现

Python doit : Create subtasks using file generated from previous task

python - 带或不带括号的 Python 函数?

python - 如何使用 pandas 将 excel 文件数据转换为 numpy 数组?

python - 只有整数、切片 (`:` )、省略号 (`...` )、numpy.newaxis (`None` ) 和整数或 bool 数组是有效的索引

java - 使用 java beans/command/java class 和 getter setter 几乎每个地方都相同是很好的实践