Вы можете видеть, что ошибка (первая, начиная с 2007 года) закрыта как "wontfix" nnorwitz, и его сообщение находится в отчете об ошибке.
Почему вы звоните Py_Initialize/Py_Finalize
более одного раза?
Почему бы не сделать что-то вроде этого (я вроде смешиваю C и
Python для удобства):
/* startup */
Py_Initialize();
/* do whatever */
while (moreFiles()) {
PyRun_SimpleString("execfile('%s')" % nextFile());
/* do whatever */
}
/* shutdown */
Py_Finalize();
Проблема в том, что большинство людей, которые пишут модули Python, не беспокоятся о том, что произойдет, если их модуль будет финализирован и повторно инициализирован, и часто не заботятся об очистке во время финализации. Авторы модулей знают, что вся память освобождается при выходе из процесса, и не беспокоятся ни о чем, кроме этого.
Так что это на самом деле не одна ошибка, это действительно тысяча ошибок - по одной на каждый модуль расширения. Это огромная работа для устранения ошибки, которая затрагивает меньшинство пользователей, большинство из которых имеют жизнеспособный обходной путь.
Вы всегда можете просто пропустить вызов на Py_Finalize
, вызов Py_Initialize
во второй раз - бездействие. Это означает, что ваше приложение будет использовать дополнительную память при первом запуске скрипта Python, и эта дополнительная память не будет возвращена ОС до тех пор, пока вы не выйдете. Пока вы все еще время от времени запускаете скрипты Python, я бы не назвал это утечкой. Ваше приложение может быть не чистым от Valgrind, но оно лучше, чем протекает как сито.
Если вам нужно выгрузить ваши (чистые) модули Python, чтобы избежать утечки памяти, вы можете сделать это. Просто удалите их из sys.modules
.
Недостатки Py_Finalize
: Если вы выполняете скрипты Python повторно, запускать между ними Py_Finalize
не имеет особого смысла. Вам придется перезагружать все модули каждый раз при повторной инициализации; мой Python загружает 28 модулей при загрузке.
Дополнительный комментарий: Ошибка не ограничивается Python. Значительное количество кода библиотеки на любом языке приведет к утечке памяти, если вы попытаетесь выгрузить и перезагрузить библиотеки. Многие библиотеки обращаются к C-коду, многие C-программисты предполагают, что их библиотеки загружаются один раз и выгружаются при выходе из процесса.