2010-09-23 3 views
5

Ich benutze Gc-Modul, um ein Leck zu debuggen.Ist das ein Speicherleck?

Es ist ein GUI-Programm und ich habe diese Funktion an eine Taste angeschlossen.

Ich habe set debug mehr auf gc.SAVE_ALL

> gc.collect() 
> 
> print gc.garbage 

und dies ist der Ausgang

[(<type '_ctypes.Array'>,), {'__module__': 'ctypes._endian', '__dict__': <attribute '__dict__' of 'c_int_Array_3' objects>, '__weakref__': <attribute '__weakref__' of 'c_int_Array_3' objects>, '_length_': 3, '_type_': <class 'ctypes.c_int'>, '__doc__': None}, <class 'ctypes._endian.c_int_Array_3'>, <attribute '__dict__' of 'c_int_Array_3' objects>, <attribute '__weakref__' of 'c_int_Array_3' objects>, (<class 'ctypes._endian.c_int_Array_3'>, <type '_ctypes.Array'>, <type '_ctypes._CData'>, <type 'object'>), (<type '_ctypes.CFuncPtr'>,), {'__module__': 'ctypes', '__dict__': <attribute '__dict__' of '_FuncPtr' objects>, '__weakref__': <attribute '__weakref__' of '_FuncPtr' objects>, '_flags_': 1, '__doc__': None, '_restype_': <class 'ctypes.c_int'>}, <class 'ctypes._FuncPtr'>, <attribute '__dict__' of '_FuncPtr' objects>, <attribute '__weakref__' of '_FuncPtr' objects>, (<class 'ctypes._FuncPtr'>, <type '_ctypes.CFuncPtr'>, <type '_ctypes._CData'>, <type 'object'>), {}, <cell at 0x10a24b0: Resource object at 0x10e6a50>, <cell at 0x10a2478: dict object at 0x11a4440>, <cell at 0x7f1703949f68: function object at 0x10ec7d0>, <cell at 0x10e2f30: NoneType object at 0x826880>, <cell at 0x10e2d70: NoneType object at 0x826880>, <cell at 0x10e2ef8: str object at 0x7f1703dd5e10>, <cell at 0x10e2de0: dict object at 0x118aaa0>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10e2f30: NoneType object at 0x826880>, <cell at 0x10a24b0: Resource object at 0x10e6a50>, <cell at 0x10e2de0: dict object at 0x118aaa0>, <cell at 0x10a2478: dict object at 0x11a4440>, <cell at 0x10e2d70: NoneType object at 0x826880>, <cell at 0x10e2ef8: str object at 0x7f1703dd5e10>, <cell at 0x7f1703949f68: function object at 0x10ec7d0>), <function _make_request at 0x10ec7d0>, (1,), {}, <cell at 0x10e2bb0: Resource object at 0x10e6a50>, <cell at 0x10e2e88: dict object at 0x119f360>, <cell at 0x10f0130: function object at 0x10ec578>, <cell at 0x10f01d8: NoneType object at 0x826880>, <cell at 0x10f01a0: NoneType object at 0x826880>, <cell at 0x10f00f8: str object at 0x7f170b05d810>, <cell at 0x10f00c0: dict object at 0x11969a0>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10f01d8: NoneType object at 0x826880>, <cell at 0x10e2bb0: Resource object at 0x10e6a50>, <cell at 0x10f00c0: dict object at 0x11969a0>, <cell at 0x10e2e88: dict object at 0x119f360>, <cell at 0x10f01a0: NoneType object at 0x826880>, <cell at 0x10f00f8: str object at 0x7f170b05d810>, <cell at 0x10f0130: function object at 0x10ec578>), <function _make_request at 0x10ec578>, (1,), {}, <cell at 0x10f0440: Resource object at 0x10e6a50>, <cell at 0x10f02b8: dict object at 0x11b2d70>, <cell at 0x10f0360: function object at 0x10ec6e0>, <cell at 0x10f0280: NoneType object at 0x826880>, <cell at 0x10f02f0: str object at 0x10ca228>, <cell at 0x10f0408: str object at 0x7f170b05d810>, <cell at 0x10f0050: dict object at 0x11b6370>, {'Accept': 'application/json', 'User-Agent': 'couchdb-python 0.6'}, (<cell at 0x10f0280: NoneType object at 0x826880>]

Die gc.garbage Liste viele Elemente hat. Bedeutet das, dass die Objekte in gc.garbage undicht sind oder gesammelt wurden oder gesammelt werden?

+0

Ich habe nie über Lecks in Python nachgedacht. Sehr gutes Beispiel! – Alexandru

Antwort

1

Von the docs:

gc.garbage

Eine Liste von Objekten, die der Sammler nicht erreichbar sein, fanden aber nicht befreit werden kann (uneinbringlich Objekte).

So sieht es aus wie eine Art von Leck zu mir. Nun geht die Dokumentation über die Zustände zu erläutern, unter denen dies auftreten könnte:

Objekte, die del() -Methoden und sind Teil eines Referenzzyklus bewirken, dass der gesamte Referenzzyklus sein uneinbringlich, einschließlich Objekte nicht unbedingt im zyklus aber nur von dort erreichbar. Python sammelt solche Zyklen nicht automatisch, da es Python im Allgemeinen nicht möglich ist, eine sichere Reihenfolge zu erraten, in der die Methoden del() ausgeführt werden. Wenn Sie eine sichere Reihenfolge kennen, können Sie das Problem erzwingen, indem Sie die Müllliste untersuchen und explizit die Zyklen aufgrund Ihrer Objekte in der Liste unterbrechen. Beachten Sie, dass diese Objekte aufgrund der Tatsache, dass sie sich in der Müllliste befinden, am Leben erhalten werden. Daher sollten sie auch aus dem Müll entfernt werden. Zum Beispiel, nach dem Abbrechen Zyklen, Del gc.garbage [:], um die Liste zu leeren. Es ist im Allgemeinen besser, das Problem zu vermeiden, indem Sie keine Zyklen erstellen, die Objekte mit Methoden del() enthalten, und in diesem Fall kann überprüft werden, ob keine solchen Zyklen erstellt werden.

nun die mit DEBUG_SAVEALL Einstellmerker macht all Ihren Müll Leck. Aus der gleichen Quelle:

gc.DEBUG_SAVEALL

Wenn gesetzt, werden alle an Müll gefunden unerreichbare Objekte angehängt wird und nicht befreit werden. Dies kann nützlich sein, um ein undichtes Programm zu debuggen.

Also, wieder, ja, diese Liste ist Speicher durchgesickert. Aber Sie sagte es alles zu lecken!

+0

Ohkay .. Also, wie finde ich die leckenden Objekte zu finden. Ich bin mir sicher, dass sie da sind. –

+0

Nun, für den Anfang schalten Sie den 'gc.DEBUG_SAVEALL' aus, der absolut alles undicht macht. Danach führen Sie den Test erneut durch. –

0

In anderen Sprachen habe ich einen Heap-Profiler mit großem Erfolg verwendet, um Speicherlecks aufzuspüren. Ich habe noch nie einen in Python benutzt, aber Heapy scheint, als wäre es einen Versuch wert.

Unter ihrer „Datenverarbeitung“ Abschnitt, versuchen Sie diese Funktion aus:

  • Berechnung des ‚dominiert‘ aus einer Reihe von Stammobjekte eingestellt, die die Menge von Objekten liefert, die, wenn die Wurzelobjekte freigegeben werden würde wurden freigegeben.

Wenn es wie andere Tools ist, sollten Sie in der Lage sein, einen Drilldown durchzuführen. Folgen Sie den Objekten mit dem größten "dominierten Set", bis Sie etwas finden, das zu groß erscheint, was wahrscheinlich ein Leck ist.