如何限制堆大小?

时间:2010-02-22 00:21:13

标签: python linux memory

我有时会编写Python程序,这些程序在执行之前很难确定它将使用多少内存。因此,我有时会调用一个试图分配大量RAM的Python程序,导致内核大量交换并降低其他正在运行的进程的性能。

因此,我希望限制Python堆可以增长的内存量。达到限制时,程序可能会崩溃。最好的方法是什么?

如果重要,很多代码都是用Cython编写的,所以它应该考虑那里分配的内存。我没有与纯Python解决方案结合(它不需要是可移植的),所以在Linux上运行的任何东西都可以。

3 个答案:

答案 0 :(得分:48)

结帐resource.setrlimit()。它只能在Unix系统上运行,但看起来它可能正是您正在寻找的东西,因为您可以使用resource.RLIMIT_DATA参数为进程和进程的子进程选择最大堆大小。

编辑:添加示例:

import resource

rsrc = resource.RLIMIT_DATA
soft, hard = resource.getrlimit(rsrc)
print 'Soft limit starts as  :', soft

resource.setrlimit(rsrc, (1024, hard)) #limit to one kilobyte

soft, hard = resource.getrlimit(rsrc)
print 'Soft limit changed to :', soft

我不确定您的用例是什么,但您可能需要使用resouce.RLIMIT_STACK来限制堆栈的大小。超过此限制将向您的进程发送SIGSEGV信号,并且为了处理它,您将需要使用备用信号堆栈,如setrlimit Linux manpage中所述。我不确定sigaltstack是否在python中实现,所以如果你想从越过这个边界恢复,这可能会很困难。

答案 1 :(得分:0)

看看ulimit。它允许设置资源配额。可能还需要适当的内核设置。

答案 2 :(得分:0)

以下代码将内存分配给指定的最大居民集大小

import resource

def set_memory_limit(memory_kilobytes):
    # ru_maxrss: peak memory usage (bytes on OS X, kilobytes on Linux)
    usage_kilobytes = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    rlimit_increment = 1024 * 1024
    resource.setrlimit(resource.RLIMIT_DATA, (rlimit_increment, resource.RLIM_INFINITY))

    memory_hog = []

    while usage_kilobytes() < memory_kilobytes:
        try:
            for x in range(100):
                memory_hog.append('x' * 400)
        except MemoryError as err:
            rlimit = resource.getrlimit(resource.RLIMIT_DATA)[0] + rlimit_increment
            resource.setrlimit(resource.RLIMIT_DATA, (rlimit, resource.RLIM_INFINITY))

set_memory_limit(50 * 1024)  # 50 mb

在linux机器上测试。