У меня есть долго работающий скрипт, который, если его запускать достаточно долго, будет занимать всю память в моей системе.
Не вдаваясь в подробности о сценарии, у меня есть два вопроса:
- Есть ли какие-либо «передовые практики», которым нужно следовать, которые помогут предотвратить возникновение утечек?
- Какие методы существуют для устранения утечек памяти в Python?
python
debugging
memory-management
memory-leaks
Fragsworth
источник
источник
__del__
методом, на которые больше не ссылаются, за исключением их цикла. Цикл не может быть разорван из-за проблем с__del__
. Почини это!Ответы:
Взгляните на эту статью: Отслеживание утечек памяти Python
Также обратите внимание, что модуль сбора мусора на самом деле может иметь установленные флаги отладки. Посмотрите на
set_debug
функцию. Кроме того, посмотрите на этот код Gnibbler для определения типов объектов, которые были созданы после вызова.источник
Я опробовал большинство вариантов, упомянутых ранее, но нашел этот небольшой и интуитивно понятный пакет лучшим: pympler
Отследить объекты, которые не были собраны в мусор, довольно просто, посмотрите на этот небольшой пример:
установить пакет через
pip install pympler
Вывод показывает вам все объекты, которые были добавлены, плюс память, которую они использовали.
Пример вывода:
Этот пакет предоставляет ряд дополнительных функций. Проверьте документацию pympler , в частности, раздел « Определение утечек памяти» .
источник
pympler
может быть МЕДЛЕННО . Если вы делаете что-то наполовину в реальном времени, это может полностью снизить производительность вашего приложения.Позвольте мне порекомендовать инструмент mem_top, который я создал
Это помогло мне решить аналогичную проблему
Это просто мгновенно показывает основные подозреваемые утечки памяти в программе Python
источник
Модуль Tracemalloc был интегрирован как встроенный модуль, начиная с Python 3.4, и, по-видимому, он также доступен для предыдущих версий Python в качестве сторонней библиотеки (хотя и не тестировал его).
Этот модуль способен выводить точные файлы и строки, которые занимали больше всего памяти. ИМХО, эта информация бесконечно более ценна, чем количество выделенных экземпляров для каждого типа (что в итоге приводит к большому количеству кортежей в 99% случаев, что является подсказкой, но в большинстве случаев едва помогает).
Я рекомендую вам использовать tracemalloc в сочетании с пиразитом . В 9 случаях из 10 запуск 10 лучших фрагментов в оболочке из пиразита даст вам достаточно информации и подсказок, чтобы исправить утечку в течение 10 минут. Тем не менее, если вы все еще не можете найти причину утечки, pyrasite-shell в сочетании с другими инструментами, упомянутыми в этой теме, вероятно, даст вам еще несколько советов. Вы также должны взглянуть на все дополнительные помощники, предоставляемые пиразитом (например, просмотрщик памяти).
источник
Вы должны специально взглянуть на ваши глобальные или статические данные (долгоживущие данные).
Когда эти данные растут без ограничений, вы также можете получить проблемы в Python.
Сборщик мусора может собирать только те данные, на которые больше нет ссылок. Но ваши статические данные могут подключать элементы данных, которые должны быть освобождены.
Другой проблемой могут быть циклы памяти, но, по крайней мере, теоретически сборщик мусора должен находить и устранять циклы - по крайней мере, до тех пор, пока они не подключены к некоторым долгоживущим данным.
Какие виды долгоживущих данных особенно неприятны? Внимательно просматривайте любые списки и словари - они могут расти без ограничений. В словарях вы, возможно, даже не увидите появления проблемы, поскольку при доступе к диктовкам количество ключей в словаре может быть не слишком заметным для вас ...
источник
Чтобы обнаруживать и обнаруживать утечки памяти для длительных процессов, например, в производственных средах, теперь вы можете использовать stackimpact . Он использует tracemalloc внизу. Больше информации в этом посте .
источник
Что касается лучших практик, следите за рекурсивными функциями. В моем случае я столкнулся с проблемами с рекурсией (там, где не было необходимости). Упрощенный пример того, что я делал:
работа таким рекурсивным способом не вызовет сборку мусора и не очистит остатки функции, поэтому каждый раз при использовании памяти растет и растет.
Мое решение состояло в том, чтобы извлечь рекурсивный вызов из my_function () и иметь дескриптор main (), когда вызывать его снова. таким образом, функция завершается естественным образом и очищается после себя.
источник
Не уверен насчет «лучших практик» для утечек памяти в python, но python должен очистить свою собственную память сборщиком мусора. Поэтому в основном я бы начал с проверки кругового списка некоторых коротких, поскольку они не будут собраны сборщиком мусора.
источник
Это ни в коем случае не исчерпывающий совет. Но первое, о чем следует помнить, когда пишете с мыслью избежать будущих утечек памяти (циклов), это убедиться, что все, что принимает ссылку на обратный вызов, должно хранить этот обратный вызов как слабую ссылку.
источник