2 votes

Est-ce que json.dumps fuite?

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)}")

En utilisant le code suivant sous Python 3.6.3, le nombre de déchets augmente sans cesse et le gestionnaire des tâches enregistre une augmentation constante de la mémoire.

Cependant, sans indentation json.dumps(self.__dict__), aucune fuite n'est observée.

Mise à jour: Code simplifié pour mettre en évidence le problème.

1voto

goldcode Points 352

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

indent=True fait simplement en sorte que json utilise l'implémentation Python au lieu de l'implémentation C. L'implémentation Python utilise des fermetures qui font référence l'une à l'autre. Un exemple simple ne concernant pas le json est le suivant :

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)}")

La "fuite" est causée par l'utilisation de gc.set_debug(gc.DEBUG_LEAK). gc.DEBUG_LEAK inclut gc.DEBUG_COLLECTABLE, gc.DEBUG_UNCOLLECTABLE et gc.DEBUG_SAVEALL.

gc.DEBUG_SAVEALL fait en sorte que les objets collectés par le ramasse-miettes soient sauvegardés dans gc.garbage pour inspection. Dans des circonstances normales, ils sont collectés.

ma réponse:

vous avez raison. J'ai réalisé plus tard que j'avais en fait une fuite dans un objet instancié avec com, j'ai supposé que c'était une fuite dans le code Python et j'ai essayé de le trouver en utilisant le module gc.

La documentation de gc m'a égaré.

gc.garbage Une liste d'objets que le collecteur a trouvés inaccessibles mais n'a pas pu libérer (objets non collectables).

j'ai supposé :

  • les références cycliques sont inaccessibles mais peuvent être libérées et donc collectables.
  • __del__ les objets finaliseurs (avec des références cycliques ?) sont inaccessibles et ne peuvent pas être libérés et donc non collectables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X