Как ограничить размер кучи? - PullRequest
47 голосов
/ 22 февраля 2010

Я иногда пишу программы на Python, в которых очень сложно определить, сколько памяти он будет использовать перед выполнением. Поэтому я иногда вызываю программу на Python, которая пытается выделить большие объемы оперативной памяти, что приводит к сильной перестановке ядра и снижению производительности других запущенных процессов.

Из-за этого я хочу ограничить объем памяти, которую может увеличить куча Python. Когда предел достигнут, программа может просто аварийно завершить работу. Какой лучший способ сделать это?

Если это имеет значение, на Cython написано много кода, поэтому он должен учитывать выделенную там память. Я не женат на чисто Python-решении (оно не должно быть переносимым), поэтому все, что работает в Linux, подойдет.

Ответы [ 3 ]

48 голосов
/ 22 февраля 2010

Извлечь 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, так что это может оказаться затруднительным, если вы захотите восстановиться после перехода через эту границу.

0 голосов
/ 04 декабря 2018

Следующий код выделяет память для указанного максимального размера резидентного набора

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.

0 голосов
/ 22 февраля 2010

Посмотрите на ulimit . Это позволяет устанавливать квоты ресурсов. Также могут потребоваться соответствующие настройки ядра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...