Утечка памяти в Python?

У меня есть скрипты Python, которые вызывают функцию foo, которая выполняет некоторые операции, используя, скажем, 10 ГБ памяти, и возвращает небольшой объект res в основную программу. После печати разрешения я удаляю их, но сверху видно, что процесс ipython все еще использует около 1 ГБ памяти. Как я могу гарантировать, что процесс освободит всю неиспользуемую память?

def foo():
   .... # some complication operation
   return res

if __name__ == "__main__":
    res = foo()
    print(res) 
    del res
    

Я пробовал использовать gc.collect(), но это ничего не меняет. Я читал, что иногда память становится фрагментированной, и Python не может освободить всю память.

Можете ли вы показать нам более точное представление вашего сценария? На данный момент del res фактически не используется, так как он в любом случае будет очищен при выходе из сценария, что является следующим шагом в этом сценарии.

C.Nivs 09.04.2024 22:13
del не удаляет объекты, а удаляет имена. Если есть какие-либо другие ссылки на объект, он не будет собирать мусор. Здесь недостаточно информации, чтобы делать что-либо кроме диких предположений. Обратите внимание: такие оболочки, как IPython, как правило, сохраняют ссылки на объекты, которые вы разрешили печатать с помощью REPL.
juanpa.arrivillaga 09.04.2024 22:13

не уверен, что это поможет, но попробуйте del другие переменные внутри foo(). Возможно, вы также захотите взглянуть на модуль сбора мусора Pythons.

Rahul Mehta 09.04.2024 22:14

@RahulMehta это точно не поможет, они все эффективно deled, когда функция возвращается

juanpa.arrivillaga 09.04.2024 22:18

Отвечает ли это на ваш вопрос? Как я могу явно освободить память в Python?

Homer512 09.04.2024 23:51
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
97
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Память не тратится зря. Скорее всего, выживет несколько небольших объектов, созданных в процессе выполнения вашей работы (например, свободные списки, хранящиеся внутри типа tuple, объекты, хранящиеся в кеше ввода-вывода, небольшие объекты, созданные фоновыми потоками IPython и т. д.), и в качестве В результате большие блоки, которые запрашивает распределитель из ОС, не могут быть возвращены, поскольку внутри них все еще находится хотя бы один живой объект.

Хотя на самом деле это не проблема. Если программе позже понадобится память, уже выделенное пространство будет использоваться повторно (дешево), прежде чем она запросит еще немного от ОС (дороже). И если память больше никогда не используется, и она действительно нужна другим процессам, память будет выгружена (или даже удалена без выгрузки, если ОС предоставляет средства подсказки памяти, которые использует распределитель, хотя CPython не делает этого в присутствует) из-за неиспользования, а физическая оперативная память будет использоваться другим процессом, которому она действительно нужна.

Эта проблема не является специфичной для Python (программы C низкого уровня, использующие malloc, могут столкнуться с той же проблемой, независимо от того, реализуют ли они свою кучу как непрерывную кучу на основе sbrk или используют специальные распределители для создания несмежной кучи mmap-сегментов. как это делает распределитель Python). Не существует волшебного способа иметь распределитель, который обрабатывает небольшие объекты, полностью избегая фрагментации и детерминированно и полностью возвращая всю неиспользуемую память в ОС.

Перестаньте беспокоиться об этом. Память дешева, ваша программа ничего не утекла (вероятно, странные расширения C могут сделать что-то неправильно и утечь, но я предполагаю, что у вас здесь нет никаких рукописных расширений C), она просто не способна вернуть все это в ОС. Это нормально, в каждой программе, на каждом языке программирования (перемещение объектов GC, выполняемое такими вещами, как среда выполнения Java, может уменьшить фрагментацию, чтобы минимизировать эту проблему, но это имеет другие издержки, которые более простые подходы, такие как те, которые используются C malloc и распределителем CPython не платите, и на практике уменьшенная фрагментация в любом случае мало что дает для возврата памяти в ОС, поэтому вы увидите то же самое поведение).

Хороший ответ, спасибо. Тот факт, что память может быть повторно использована процессом в дальнейшем, обнадеживает.

motam79 11.04.2024 19:39

Обратите внимание, что gc.collect() не обязательно освобождает всю неиспользуемую память, но может помочь освободить память, которая больше не используется.

Система управления памятью Python, включая сборщик мусора, не предназначена специально для обработки фрагментации памяти на уровне базового распределителя памяти.

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

Другие вопросы по теме