0

J'utilise des dictionnaires dans mon script python écrit en python 2.7. Quand j'ai exécuté mon script en utilisant pympler pour trouver une fuite de mémoire, j'ai trouvé que la taille de l'objet liste augmente incroyablement.Liste interne contenant dictionnaire clés n'a pas la mémoire désaffecter même après la suppression des clés du dictionnaire

Et ces liste contient les clés de ces dictionary.Is ces listes dans la mise en œuvre de construction du dictionnaire python?

sortie de pympler est comme suit:

      types | # objects | total size 
    ============================ | =========== | ============ 
        list |  99221 | 106.53 MB 
        str |  105530 |  6.06 MB 
        dict |   602 | 940.48 KB 
        code |  1918 | 239.75 KB 
        int |  10043 | 235.38 KB 
     wrapper_descriptor |  1120 |  87.50 KB 
        type |   87 |  76.80 KB 
builtin_function_or_method |   719 |  50.55 KB 
     method_descriptor |   601 |  42.26 KB 
        set |   132 |  33.41 KB 
       weakref |   372 |  31.97 KB 
        tuple |   364 |  26.24 KB 
    <class 'abc.ABCMeta |   20 |  17.66 KB 
     member_descriptor |   233 |  16.38 KB 
    function (__init__) |   114 |  13.36 KB 

La taille de la liste augmente et la mémoire RES pour la scipt est également incresing? La liste contient les clés du dictionnaire utilisé dont je pense que c'est l'implémentation interne du dictionnaire. Est-ce que les clés sont stockées en tant que liste dans la mémoire? Comment pourrais-je gérer cette fuite de mémoire?

Voici le code pour la sortie ci-dessus:

  from pympler import tracker 
     from pympler import summary 
     from pympler import muppy 
     import types 
     while(1): 
      d={} 
      for i in range(1000,1100): 
      d[i]=1 
      for i in range(1000,1050): 
      del d[i] 
      all_objects = muppy.get_objects() 
      sum1 = summary.summarize(all_objects) 
      summary.print_(sum1) 
      type = muppy.filter(all_objects, Type=types.ListType) 
      print 'length :%s'%(len(type)) 
+1

Votre titre contient une affirmation que votre question révèle une hypothèse. Avez-vous testé cela? Pourriez-vous fournir un exemple minimal que d'autres pourraient utiliser pour recréer ce comportement? – jonrsharpe

+0

"La liste contient les clés du dictionnaire utilisé dont je pense que c'est l'implémentation interne du dictionnaire." Nan; l'implémentation interne d'un dictionnaire n'a pas de liste. Voir [ 'dictobject.c'] (https://hg.python.org/cpython/file/4e81b20e7a57/Objects/dictobject.c) pour la façon dont ils fonctionnent réellement. – abarnert

+0

J'ai édité ma question avec l'exemple de code.J'ai testé le code le code et la sortie de pympler est également affichée –

Répondre

4

Votre problème est un artefact de test mal les choses.

Dans votre boucle, vous faites ceci:

all_objects = muppy.get_objects() 

Vous supprimez jamais all_objects, la liste précédente de tous les objets est encore un objet en direct au moment où vous appelez get_objects. Bien sûr, vous laissez tomber cette référence lorsque vous affectez la nouvelle liste à all_objects, mais c'est trop tard; la nouvelle liste de tous les objets a maintenant une référence à l'ancienne liste de tous les objets. Il s'agit en fait d'un problème courant avec les personnes qui utilisent toutes sortes d'outils de débogage de la mémoire en cours de traitement. Il est facile de conserver les artefacts de l'outil et de déboguer ces objets.

Une belle façon de vous assurer que vous ne faites pas accidentellement ce genre de chose est de prendre en compte votre code Muppy en fonction:

def summarize(): 
    all_objects = muppy.get_objects() 
    sum1 = summary.summarize(all_objects) 
    summary.print_(sum1) 
    type = muppy.filter(all_objects, Type=types.ListType) 
    print 'length :%s'%(len(type)) 

Maintenant, dans la boucle, vous pouvez simplement appeler summarize(), et assurez-vous que vous ne pouvez pas avoir des variables locales qui traînent que vous ne vouliez pas.