[PYTHON] Filtrer la sortie de tracemalloc

Actuellement, il existe un module standard appelé tracemalloc comme module pour vérifier quelle variable alloue la quantité de mémoire dans un programme Python.

Si vous l'utilisez, par exemple, en écrivant un tel code, vous pouvez vérifier l'omission de libération de mémoire d'un certain processus.

Code qui appelle directement tracemalloc


import tracemalloc

tracemalloc.start()
snap1 = tracemalloc.take_snapshot()
size1 = sum([stat.size for stat in snap1.statistics("filename")])
for stat in snap1.statistics('lineno')[:10]:
  print(stat)
# ...Certains traitements...
snap2 = tracemalloc.take_snapshot()
size2 = sum([stat.size for stat in snap2.statistics("filename")])
for stat in snap2.compare_to(snap1, 'lineno')[:10]:
  print(stat)
diff = abs(size1 - size2)
print("Quantité de mémoire après traitement{:,}Travail à temps partiel".format(diff))    

Si vous utilisez la syntaxe with, cela ressemble à ceci

Classé pour utiliser la syntaxe with


import tracemalloc

class MemCheck:
  """
Une classe pour effectuer des vérifications de mémoire. Utilisé dans la syntaxe with.
Un contrôle est automatiquement effectué lors de la sortie avec.
  """

  def __init__(self):
    """
Initialisation
    """
    pass

  def __enter__(self):
    tracemalloc.start()
    self.snap = tracemalloc.take_snapshot()
    self.size = sum([stat.size for stat in self.snap.statistics("filename")])
    print("")
    print("-----TEST START!!!!-----")
    for stat in self.snap.statistics('lineno')[:10]:
      print(stat)
    return self

  def __exit__(self, ex_type, ex_value, trace):
    print("-----TEST END!!!!!!-----")
    snap = tracemalloc.take_snapshot()
    size = sum([stat.size for stat in snap.statistics("filename")])
    for stat in snap.compare_to(self.snap, 'lineno')[:10]:
      print(stat)
    diff = abs(self.size - size)
    print("Quantité de mémoire après traitement{:,}Travail à temps partiel".format(diff))
    print("-" * 20)
    return False

def main():
  with MemCheck():
    # ...Certains traitements...

Cependant, si vous déplacez réellement cela, les objets qui utilisent la mémoire incluront l'intérieur du module tracemalloc et l'objet pour le fonctionnement du débogueur, il est donc un peu gênant de l'utiliser pour tester les fuites de libération de mémoire.

À cette fin, il existe une méthode appelée filter_traces () pour filtrer les données.

Cependant, si vous regardez le document, seuls deux exemples sont écrits, donc cela correspond à la situation «Je veux ignorer complètement l'objet pour le débogage» ou inversement «Je veux tester uniquement le code que j'ai écrit» ne peux pas.

Que dois-je faire lorsque je spécifie un nom de dossier et que je dis "Je ne souhaite tracer que les fichiers de ce dossier"?

fais ça

Vous pouvez l'écrire comme suit.

Un exemple qui utilise la syntaxe with avec un filtre ajouté


import tracemalloc
from pathlib import Path

class MemCheck:
  """
Une classe pour effectuer des vérifications de mémoire. Utilisé dans la syntaxe with.
Un contrôle est automatiquement effectué lors de la sortie avec.
  """

  def __init__(self):
    """
Initialisation
    """
    pass

  def __enter__(self):
    tracemalloc.start()
    self.snap = tracemalloc.take_snapshot().filter_traces(self.get_filter_traces())
    self.size = sum([stat.size for stat in self.snap.statistics("filename")])
    print("")
    print("-----TEST START!!!!-----")
    for stat in self.snap.statistics('lineno')[:10]:
      print(stat)
    return self

  def __exit__(self, ex_type, ex_value, trace):
    print("-----TEST END!!!!!!-----")
    snap = tracemalloc.take_snapshot().filter_traces(self.get_filter_traces())
    size = sum([stat.size for stat in snap.statistics("filename")])
    for stat in snap.compare_to(self.snap, 'lineno')[:10]:
      print(stat)
    diff = abs(self.size - size)
    print("Quantité de mémoire après traitement{:,}Travail à temps partiel".format(diff))
    print("-" * 20)
    return False

  #ajouter à
  def get_filter_traces(self):
    return (
      tracemalloc.Filter(True, str(Path(__file__).parent.parent / ".venv" / "lib" / "site-packages" / "*")),
      tracemalloc.Filter(True, str(Path(__file__).parent.parent / "src" / "*")),
    )

def main():
  with MemCheck():
    # ...Certains traitements...

La méthode get_filter_traces () dans le code est la méthode qui renvoie la liste de filtres pour la méthode filter_traces (). Je fais cela parce que je veux que le filtre soit appliqué à tous les processus d'acquisition de clichés.

L'argument de la méthode filter_traces () reçoit maintenant un tapple de l'objet tracemalloc.Filter, et l'objet tracemalloc.Filter a le premier argument du constructeur qui" affiche ce qui correspond à ce filtre ". Spécifiez "(True)" ou "Afficher les incohérences (False)" et spécifiez le nom de fichier à spécifier dans le filtre dans le deuxième argument (filename_pattern).

En regardant ce nom de fichier et ce document, il est dit "Modèle de nom de fichier du filtre (str). Propriété en lecture seule." Donc, à première vue, il est normal d'insérer une expression régulière, mais à la place, c'est un module appelé ** fnmatch Spécifie une chaîne de caractères génériques au format Shell qui peut être traitée) **

Si vous êtes habitué à utiliser des correspondances de modèles telles que des expressions régulières, vous pouvez penser que motif = expression régulière, mais veuillez noter que ce n'est pas une expression régulière. Si c'est le cas, je voulais que vous écriviez un commentaire qui vous ferait bien comprendre ...

Si seuls les fichiers du dossier src sont ciblés pour le traçage, rien ne peut apparaître.

Si ce n'est pas le programme lui-même que vous avez écrit mais l'objet que vous avez appelé dans le programme que vous avez écrit **, vous devez l'écrire vous-même avec tracemalloc.take_snapshot (). Ce n'est pas le numéro de ligne du fichier source qui a été utilisé, mais le numéro de ligne du fichier source qui définit l'objet appelé ** (j'ai appelé PyPDF.PdfFileReader avec mon programme, et la mémoire lue n'a pas été libérée. Dans le cas, "La mémoire est allouée dans les fichiers sous \ lib \ site-packages \ PyPDF2 \ "s'affiche).

Par conséquent, lors de la création d'un filtre, non seulement "sous le dossier src" mais également le "dossier du module appelant" comme dans l'exemple ci-dessus doivent être inclus dans la cible de trace. Si le dossier d'environnement virtuel est créé dans le projet, c'est OK si la cible de recherche est autour de .venv \ lib \ site-packages \ * comme décrit ci-dessus.

Comment as-tu remarqué

J'ai ouvert le fichier C: \ PythonNN \ Lib \ tracemalloc.py et suivi le processus de filtrage (barre).

Je veux que vous pardonniez le comportement que vous ne pouvez pas comprendre sans faire cela ...

Recommended Posts

Filtrer la sortie de tracemalloc
Sortie du nombre de cœurs de processeur en Python
Paramètre pour afficher le journal de l'exécution de cron
Lire la sortie du sous-processus, ouvrir en temps réel
Sortie sous la forme d'un tableau python
J'ai essayé d'utiliser le filtre d'image d'OpenCV
Le début de cif2cell
le zen de Python
L'histoire de sys.path.append ()
Bases de python: sortie
La vengeance des types: la vengeance des types
Afficher progressivement la sortie de la commande exécutée par le sous-processus.
[python] option pour désactiver la sortie de click.progressbar
J'ai vérifié les spécifications de sortie du LSTM bidirectionnel de PyTorch
Afficher le résultat de sortie de sklearn.metrics.classification_report sous forme de fichier CSV
Grattage du résultat de "Schedule-kun"
L'histoire de la construction de Zabbix 4.4
Sauvegardez la sortie de GAN une par une ~ Avec l'implémentation de GAN par PyTorch ~
Vers la retraite de Python2
Comparez les polices de jupyter-themes
Expliquez le code de Tensorflow_in_ROS
Fonctionnement du filtre (Aucun, liste)
Réutiliser les résultats du clustering
GoPiGo3 du vieil homme
Calculez le nombre de changements
La popularité des langages de programmation
Changer le style de matplotlib
Visualisez la trajectoire de Hayabusa 2
À propos des composants de Luigi
Composants liés du graphique
Sortie de débogage de la commande calice
Keras Je veux obtenir la sortie de n'importe quelle couche !!
À propos de la sortie HOG de Scikit-Image
À propos des fonctionnalités de Python
Sortie du résultat de la méthode de descente de dégradé sous forme d'animation matplotlib
Simulation du contenu du portefeuille
Le pouvoir des pandas: Python
Je veux sortir le début du mois prochain avec Python
Lire la sortie standard d'un sous-processus ligne par ligne en Python
Comment afficher le résultat de sortie de la commande man Linux dans un fichier
Fonction de filtre Amazon Rekognition lors de l'enregistrement des visages ・ Limitation du nombre de visages
Comprendre le nombre de paramètres d'entrée / sortie du réseau neuronal convolutif
Lignes de sortie contenant la chaîne spécifiée
Les spécifications de pytz ont changé
Trouvez la définition de la valeur de errno
jour de course des dockers (note)
Tracez la propagation du nouveau virus corona
L'histoire de Python et l'histoire de NaN
Élever la version de pyenv elle-même
Obtenez le nombre de vues de Qiita
[Python] La pierre d'achoppement de l'importation
First Python 3 ~ Le début de la répétition ~
Traduction japonaise du manuel e2fsprogs
Changer l'arrière-plan d'Ubuntu (GNOME)
La probabilité de précipitation est-elle correcte?
Mise en place d'un filtre à particules simple
J'ai étudié le mécanisme de connexion flask!
Comprendre le contenu du pipeline sklearn