Ответ 1
Python - это собранный мусором язык. Если значение больше не "доступно" из вашего кода, оно в конечном итоге будет удалено.
Оператор del
, как вы видели, удаляет привязку вашей переменной. Переменные - это не значения, они просто имена для значений.
Если эта переменная была единственной ссылкой на значение в любом месте, значение в конечном итоге будет удалено. В частности, в CPython сборщик мусора построен поверх подсчета ссылок. Таким образом, "в конечном итоге" означает "немедленно". * В других реализациях это обычно "довольно скоро".
Однако, если были другие ссылки на одно и то же значение, просто удалить одну из этих ссылок (будь то через del x
, x = None
, выходя из области, где существует x
и т.д.), ничего не очищает. **
Здесь есть еще одна проблема. Я не знаю, что действительно делает модуль memory_profiler
(предположительно этот), но описание (говорящее об использовании psutil
) звучит так, будто оно измеряет ваши использование памяти из "снаружи".
Когда Python освобождает хранилище, он не всегда или даже обычно возвращает его в операционную систему. Он хранит "бесплатные списки" на нескольких уровнях, поэтому он может быстрее использовать память быстрее, чем если бы ей пришлось вернуться к ОС, чтобы попросить больше. В современных системах это редко бывает проблемой - если вам нужна память снова, хорошо, что у вас это было; если вы этого не сделаете, он будет выгружен, как только кому-то это понадобится, и никогда не будет выгружен обратно, так что там будет мало вреда.
(Кроме того, который я назвал "ОС" выше, на самом деле представляет собой абстракцию, состоящую из нескольких уровней, из библиотеки malloc
через основную библиотеку C в ядро /пейджер и по меньшей мере одну из этих уровней обычно имеют свои собственные бесплатные списки.)
Если вы хотите отслеживать использование памяти с внутренней точки зрения... ну, это довольно сложно. В Python 3.4 стало намного проще благодаря новому модулю tracemalloc
. Существуют различные сторонние модули (например, heapy
/guppy
, Pympler
, meliae
), которые пытаются получить такую же информацию с более ранними версиями, но это сложно, поскольку получение информации от различных распределителей и привязка этой информации к мусору коллекционер, был очень тяжелым до PEP 445.
* В некоторых случаях есть ссылки на значение... но только из других ссылок, которые сами недостижимы, возможно, в цикле. Это все еще считается "недостижимым" в отношении сборщика мусора, но не касается количества ссылок. Таким образом, у CPython также есть "детектор цикла", который работает так часто и находит циклы достижимых друг друга, но не достижимых значений, и очищает их.
** Если вы тестируете в интерактивной консоли, могут быть скрытые ссылки на ваши значения, которые трудно отслеживать, поэтому вы можете подумать, что избавились от последней ссылки, когда вы этого не сделали. В script всегда должно быть возможно, если не просто, разобраться в деталях. Модуль gc
может помочь, как и отладчик. Но, конечно, оба они также дают вам новые способы добавления дополнительных скрытых ссылок.