Jak odstranit nepotřebnou instanci třídy z paměti

Dotaz z konference

Pratele, potreboval bych poradit jak uvolnit pamet v pythonu, respektive jak odstranit nepotrebnou instanci tridy z pameti. Zkousel jsem prikaz del. Po provedeni "del" na instanci tridy je vsak pamet zaplnena furt stejne (sledovano pomoci top v linuxu). Mozna na to jdu uplne spatne. Vi nekdo jak provest uvolneni?

Odpověď

Po použití del se jen "smaže" proměnná a tím odstraní reference na daný objekt. Objekt se uvolní až pokud na něj nejsou žádné reference (ihned nebo až si toho všimne garbage collector, záleží na implementaci a okolnostech). Ale dejme tomu, že se objekt skutečně smaže, protože jste zavolal del na jedinou referenci. Pak se paměť uvolní, jenže se jedná o paměť, kterou má python alokovanou právě pro objekty, tedy se uvolní místo třeba pro nový objekt; paměť není vrácena operačnímu systému (= žádná změna ve výpisu top), bylo by to neefektivní vždy vracet každý kousek uvolněné paměti a pak zase alokovat další (vlastně celý tenhle problém je o kompromisech mezi výkonem a zabranou pamětí, i volání malloc/free je dost drahé).

Pokud se ale takto nastřádá hodně nevyužité paměti, interpreter se může rozhodnout tuto paměť vrátit operačnímu systému. Ale záleží, jak bylo tato paměť od operačního systému získána (pokud je použita funkce malloc, záleží na implementaci v libc). Pokud se jedná o namapovanou paměť (mmap) a celý blok paměti (přinejmenším celá stránka) je nepotřebný, lze ho vrátit a hodnota v top se - konečně - sníží. Paměť lze od operačního systému získat i jinými způsoby, to bych zde ale už raději nerozváděl.

V důsledku toho se může stát, že při smazání velkého objektu se nemusí uvolnit tolik paměti, kolik ten objekt zabíral. Pokud si s tím chcete hrát, doporučuji strace :-)

To, co jsem teď napsal, je dost zjednodušené a zobecněné, napsal jsem to bez konkrétní znalosti vnitřností Pythonu, které se navíc s vývojem Pythonu a jeho interpreterů mění.[...]

Mimochodem, nedávno se na Python mailing-listu ozval někdo s dotazem, jestli nelze mít objekt naalokovaný řekněme dokud je volná paměť, že by pak třeba sám zmizel. Nelze :-) Lze ale použít třeba memcache.