Korzystanie objgraph, znalazłem kilka obiektów tak:Czy Python GC radzi sobie z takimi cyklami odniesienia?
śmieci sprawa kolektor Pythona z cykli takich jak ta, lub będzie przeciekać?
Nieco szersza pętli:
Korzystanie objgraph, znalazłem kilka obiektów tak:Czy Python GC radzi sobie z takimi cyklami odniesienia?
śmieci sprawa kolektor Pythona z cykli takich jak ta, lub będzie przeciekać?
Nieco szersza pętli:
Standardowy mechanizm liczenia referencji Pythona nie może zwolnić cykli, więc struktura w tym przykładzie wycieknie.
supplemental garbage collection facility jednak jest domyślnie włączona i powinna być w stanie uwolnić tę strukturę, jeśli żaden z jej elementów są dostępne z zewnątrz już i nie mają __del__()
metod.
Jeśli tak, śmieciarka will not free them, ponieważ nie może określić bezpiecznego celu uruchomienia tych metod __del__()
.
Należy wyraźnie stwierdzić, że GC, który nazywacie "uzupełniającym", jest domyślnie włączony w Pythonie –
@Eli, masz rację, odpowiedź odpowiednio zaktualizowana. –
Hurra! Przynajmniej narody (ty i Raymond Hettinger), którzy nie robią zamieszania wokół GC, a nie używają "garbage collector" jako synonimu "mechanizmu liczącego referencje"! Od dawna byłem zakłopotany faktem, że rozumiałem takie rzeczy, ale ciągle czytałem teksty, w których narody wyrażały swoje idee tak, jakby GC był odpowiedzialny za zabijanie niesklasyfikowanych obiektów. W twojej odpowiedzi różnica jest doskonale wyrażona i jasna. Dziękuję Ci. Stąd +1 – eyquem
Pythona GC jest przeznaczony do przechodzenia wszystkie ruchome obiekty zlokalizować i usunąć cykle odniesienia bez odniesienia zewnętrznego.
Można sprawdzić, czy tak się dzieje, uruchamiając gc.collect()
, a następnie drukując gc.garbage
i gc.get_objects.
Jeśli użyjesz słabych punktów dla swoich rodziców, GC stanie się normalne.
Aby nieco rozszerzyć odpowiedź Frédéric, the "reference counts" section dokumentów wyjaśnia ładnie detekcję cyklu dodatkowego.
Ponieważ uważam wyjaśniania rzeczy to dobry sposób, aby potwierdzić rozumiem, oto kilka przykładów ... Z tych dwóch klas:
class WithDel(object):
def __del__(self):
print "deleting %s object at %s" % (self.__class__.__name__, id(self))
class NoDel(object):
pass
Tworzenie obiektu i utraty odwołanie od a
wywołuje metodę __del__
dzięki ref liczenia:
>>> a = WithDel()
>>> a = None # leaving the WithDel object with no references
deleting WithDel object at 4299615184
przypadku wprowadzenia pętla odniesienia między dwoma obiektami bez__del__
sposobu, całość pozostaje szczelny, t jego czas dzięki wykrywaniu cyklu.Po pierwsze, umożliwia wyjście śmieci zbierania debugowania:
>>> import gc
>>> gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS)
następnie dokonać pętla odniesienia między dwoma obiektami:
>>> a = NoDel(); b = NoDel()
>>> a.other = b; b.other = a # cyclical reference
>>> a = None; b = None # Leave only the reference-cycle
>>> gc.collect()
gc: collectable <NoDel 0x10046ed50>
gc: collectable <NoDel 0x10046ed90>
gc: collectable <dict 0x100376c20>
gc: collectable <dict 0x100376b00>
4
>>> gc.garbage
[]
(dict
wynosi od obiektów wewnętrzny atrybutu __dict__
)
Wszystko jest w porządku, do nawet jeden z obiektów w cyklu zawiera metodę __del__
:
>>> a = NoDel(); b = WithDel()
>>> a.other = b; b.other = a
>>> a = None; b = None
>>> gc.collect()
gc: uncollectable <WithDel 0x10046edd0>
gc: uncollectable <dict 0x100376b00>
gc: uncollectable <NoDel 0x10046ed90>
gc: uncollectable <dict 0x100376c20>
4
>>> gc.garbage
[<__main__.WithDel object at 0x10046edd0>]
Jak wspomniano Paul, pętla może zostać uszkodzony z weakref
:
>>> import weakref
>>> a = NoDel(); b = WithDel()
>>> a.other = weakref.ref(b)
>>> b.other = a # could also be a weakref
Potem, gdy odniesienie do obiektu WithDel
b
jest stracone, to zostanie usunięty, mimo cyklu:
>>> b = None
deleting WithDel object at 4299656848
>>> a.other
<weakref at 0x10045b9f0; dead>
Och, objgraph byłoby pomocne indicated the problematic __del__
method like this
Ważne: https://stackoverflow.com/ q/15974561/1959808 –