Вы можете видеть, что ошибка (первая, с 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-clean, но это лучше, чем утечка, как сито.
Если вам нужно выгрузить ваши (чистые) модули Python, чтобы избежать утечки памяти, вы можете это сделать. Просто удалите их с sys.modules
.
Недостатками Py_Finalize
: Если выполнение сценариев Python несколько раз, это не имеет особого смысла для запуска Py_Finalize
между ними. Вам придется перезагружать все модули каждый раз, когда вы повторно инициализируете; мой Python загружает 28 модулей при загрузке.
Дополнительная информация: Ошибка не ограничивается Python. Значительная часть кода библиотеки на любом языке будет утечка памяти, если вы попытаетесь выгрузить и перезагрузить библиотеки. Многие библиотеки вызывают код C, многие программисты C предполагают, что их библиотеки загружаются один раз и выгружаются при выходе из процесса.
Спасибо, хотя это немного разочаровывает, что нет простого решения. По крайней мере, это подтверждает мой нынешний подход. – user1140116
Что вы пытаетесь достичь? (Часто *, что * можно решить.) –
Я создаю IDE Python, который будет многократно выполнять скрипты python. Каждый раз, когда выполняется сценарий, память, потребляемая программой, увеличивается. Я вызываю Py_Initialize при запуске приложения и никогда не вызываю Py_Finalize (как вызвано boost :: python). Сценарии содержат библиотеки, включая PyOpenGL и PyQt. Я столкнулся с проблемами, в частности, с памятью, которая никогда не освобождается при использовании QImage. – user1140116