2017-11-15 2 views
2
import gc, json 

class leak(object): 
    def __init__(self): 
     pass 

gc.set_debug(gc.DEBUG_LEAK) 
while True: 
    leak_ = leak() 
    json.dumps(leak_.__dict__, indent=True) 
    gc.collect() 
    print(f"garbage count: {len(gc.garbage)}") 

Mit dem folgenden Code unter Python 3.6.3 erhöht sich die Anzahl der Speicherabfälle und Task-Manager verzeichnet stetigen Speicher erhöhen.Leckt json.dumps?

Jedoch ohne Eindruck json.dumps(self.__dict__), wird kein Leck beobachtet.

Aktualisieren: Code wurde vereinfacht, um das Problem hervorzuheben.

Antwort

1

ref: https://bugs.python.org/issue32045

indent=True macht nur json statt Implementierung von C Python-Implementierung zu verwenden. Die Python-Implementierung verwendet Closures, die sich gegenseitig referenzieren. Einfaches Beispiel nicht json beteiligt ist:

import gc 

def f(): 
    def g(): 
     return h 
    def h(): 
     return g 
    return 

gc.set_debug(gc.DEBUG_LEAK) 
while True: 
    f() 
    gc.collect() 
    print(f"garbage count: {len(gc.garbage)}") 

Der "Leck" wird verursacht durch die Verwendung gc.set_debug (gc.DEBUG_LEAK). gc.DEBUG_LEAK enthält gc.DEBUG_COLLECTABLE, gc.DEBUG_UNCOLLECTABLE und gc.DEBUG_SAVEALL.

gc.DEBUG_SAVEALL bewirkt, dass Objekte, die im Müll gesammelt wurden, in gc.garbage zur Überprüfung gespeichert werden. Unter normalen Umständen werden sie gesammelt.

meine Antwort:

Sie richtig sind. Ich erkannte später, ich hatte tatsächlich ein Leck in einem com instanziierten Objekt, angenommen, es war ein Leck in der Python und versuchte, es mit dem GC-Modul zu finden.

Die GC-Dokumentation führte mich den Gartenweg hinunter.

gc.garbage Eine Liste von Objekten, die der Sammler seine unerreichbar gefunden, aber nicht befreit werden kann (uneinbringlich Objekte).

i angenommen:

  • zyklische Referenzen nicht erreichbar sind und damit aber sammelbaren befreit werden können.
  • __del__ Finalizer (mit zyklischen Referenzen?) Objekte sind nicht erreichbar und können nicht freigegeben und daher nicht einholen.