Python 2.4 не освобождает память
Как я уже не раз говорил, libmapi нещадно течёт. Я сейчас работаю с версией из транка, 921-й комит, это довольно старая версия (текущий коммит — 1303), но утечки находят до сих пор и впереди их немало. Память течёт быстро и при получении больших объёмов данных утекает раньше, чем данные удаётся получить.
Поэтому я изолирую libmapi в отдельном процессе, получаю данные, пока могу и отдаю их «наверх» — родителю, потом делаю новый процесс и получаю следующую пачку. Для того, чтобы отдать данные родителю я использую os.pipe, а данные туда можно передавать только строкой. Так как данные у меня сложные, я их сериализую при помощи cPickle, а для сериализации нужна память.
Где взять память, если всё, что было доступно процессу, съела libmapi? Я пытался выделать память при помощи list(range(20 * 1024 * 1024)), а перед сериализацией удалять, но это не работало. Сегодня я узнал почему. Оказывается Python до версии 2.5 никогда не освобождает память. У меня как раз Python 2.4, приехали.
P.S. Чтобы предотвратить вопросы для чего я делаю list(range(…)), расскажу сразу: для совместимости с Python 3.0, на который мы все когда-нибудь перейдём. Там range возвращает итератор.
Добавлено позднее.
Я сейчас немного поисследовал, сделал замеры и выяснил, что если обращаться к аллокатору памяти Python напрямую (например, через ctypes), то память возвращается:
from ctypes import *
mem = pythonapi.PyMem_Malloc(c_size_t(100*1024*1024))
pythonapi.PyMem_Free(mem)