Запустите это:
for i in range(1000000000):
a = []
Похоже, создаваемые объекты списка никогда не помечаются для сборки мусора. Из профилировщика памяти похоже, что кадр стека интерпретатора удерживает все объекты списка, поэтому GC никогда ничего не может с этим поделать.
Это задумано?
EDIT:
Вот лучший пример проблемы. Запустите приведенный ниже код с помощью профилировщика памяти:
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
a = [b for b in range(1000000)]
Вы увидите, что память, выделенная во время обработки списка, никогда не собирается сборщиком мусора. Это связано с тем, что на все созданные объекты ссылается объект InterpreterFrame в DLR.
Теперь запустите это:
def get():
return [b for b in range(1000000)]
a = get()
a = get()
a = get()
a = get()
a = get()
a = get()
a = get()
Под профилировщиком вы можете видеть, что память здесь собирается как следует. Я предполагаю, что это работает, потому что InterpreterFrame функции очищается при выходе из функции.
Так это ошибка? Кажется, что это приведет к некоторым довольно серьезным утечкам памяти, когда он находится внутри фреймов (контекстов?) Скрипта IronPython.