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"?
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 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.
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