Portál AbcLinuxu, 4. května 2025 22:16
Nedávno som začal viac-menej z donútenia (škola) robiť nejaký program ako semestrálku v pythonovi. Konkrétne som si povedal, že urobím gui k boinc_client-ovi. Prekvapilo ma ale, že aplikácia zaberá stále viac RAM.
Takže po dlhom skúmaní som došiel k záveru, že problém je niekde okolo riadku s data = QVariant.fromList(...). Tak som urobil malý programík v pythonovi na ktorom by som si vyskúšal ako sa dá uvoľniť táto pamäť. Takže obsah toho malého programíku:
from PyQt4.QtCore import QVariant while True: zoznam = QVariant.fromList([QVariant('text1'), QVariant('text2')]) zoznam.clear() del(zoznam)
Predpokladám, že tento kód v pythonovi by mal byť ekvivalentný s nasledujúcim programom v C++:
#include <QVariant> #include <QList> int main(int argc, char *argv[]) { while (1) { QList<QVariant> zoznam; zoznam.append(QVariant("text1")); zoznam.append(QVariant("text2")); QVariant variant = QVariant(zoznam); } }
Napriek tomu po spustení programu v pythonovi sa obsadená RAM stále zväčšuje zatiaľ čo v C++ nie. Robím niečo zle alebo je chyba skutočne niekde mimo môjho kódu? Robí to problémy aj ostatným užívateľom alebo len mne (napríklad preto, že PyQt4 zle skompiloval)?
Pre tých ktorí chcú vidieť čo to vlastne robím som prihodil aj screenshoty, prípadne môžete pozrieť video, zdrojové kódy nedám, hambím sa za ne.
Tiskni
Sdílej:
QVariant variant = QVariant(zoznam);Ten řádek je k ničemu...
noo, medzi tymi testami je viacero rozdielov... najzasadnejsi ale asi v tom, ze v c++ kode sa ti tie objekty naozaj uvolnia z RAM, kym v pythone je garbage collector.. skus tam este ked tak pridat import gc; gc.collect() za ten kod 'del'
gc.set_debug(gc.DEBUG_LEAK)
. V gc.garbage
bys pak měl mít seznam objektů, které se nedají uvolnit.
gc.collect()
program spíše jenom zpomalí, takže se zdá, že to něco řeší, ale vždy vrátí 0 uvolněných objektů. Co narůstá je počet objektů (gc.get_objects()
), přičemž garbage collector se zdá pracuje, protože počet objektů v jednotlivých generací gc.get_count()
roste, ale taky klesá.
Při nastaveném gc.DEBUG_STATS to naopak vypadá, že collector nepracuje, protože počet objektů roste. Ale ony si údaje gc.get_count()
a to, co vypisuje gc samotný, moc neodpovídají.
gc: done. gc: collecting generation 0... gc: objects in each generation: 703 6300 58705 gc: done. gc: collecting generation 0... gc: objects in each generation: 703 7000 58705 gc: done. gc: collecting generation 1... gc: objects in each generation: 703 7700 58705 gc: done. gc: collecting generation 0... gc: objects in each generation: 703 0 67105Podle mě je to bug a mělo by to být oznámeno autorům PyQt4.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.