Освобождение памяти ОС после тяжелых функций без принудительного использования GCPython

Программы на Python
Ответить
Anonymous
 Освобождение памяти ОС после тяжелых функций без принудительного использования GC

Сообщение Anonymous »

У меня есть функция Python, которая потребляет большой объем памяти. Когда функция завершится, я хочу освободить память и вернуть освобожденные страницы операционной системе, вызвав malloc_trim(0).
Однако память не освобождается сразу — она освобождается только после сборки мусора поколения 2.
Мой первый подход
Я попробовал вызвать:

Код: Выделить всё

gc.collect()
malloc_trim(0)
вручную после возврата функции.
Это работает, но документация Python предупреждает, что:

Эффект вызова gc.collect(), когда интерпретатор уже выполняет сбор, не определен.

Таким образом, этот подход потенциально может вызвать неопределенное поведение, что делает его небезопасным для использования в рабочей среде.
/>Мой второй подход
Вместо этого я попробовал дождаться естественной коллекции gen=2, а затем вызвать malloc_trim.
Я сделал это, зарегистрировав обратный вызов GC:

Код: Выделить всё

def gc_trim_callback(phase, info):
if phase == "stop" and info["generation"] == 2:
malloc_trim(0)
gc.callbacks.remove(gc_trim_callback)

gc.callbacks.append(gc_trim_callback)
Это работает правильно, когда действительно происходит сбор данных поколения 2 — срабатывает обратный вызов и запускается malloc_trim.
Проблема
Проблема в том, что иногда после завершения тяжелой функции процесс простаивает до того, как произойдет сбор данных поколения 2.
Если пользователь не выполняет никаких дальнейших действий, процесс может простаивать в течение часов, дней или даже месяцев, сохраняя неиспользованную память на неопределенный срок. Это неприемлемо для моего варианта использования.
Я придумал два очень плохих решения для запуска коллекции поколения 2 «естественным образом»:
  • Регулировка порога GC с помощью gc.set_threshold(), чтобы коллекции поколения 2 происходили чаще, — но это кажется хакерским и может отрицательно повлиять на производительность.
  • Создание большого количества искусственных циклов ссылки после возврата функции, а затем освобождая их для запуска коллекции gen2 — тоже очень хакерски и неэффективно.
Короче говоря, я не могу запустить коллекцию gen2, поскольку это может привести к недопустимому поведению. Я могу добиться этого с помощью некоторых манипуляций, которых хочу избежать. Можете ли вы придумать лучшее решение, чем то, что есть у меня?

Подробнее здесь: https://stackoverflow.com/questions/798 ... forcing-gc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»