Maison  >  Article  >  Tutoriel système  >  Comment détecter et résoudre les fuites de mémoire sous Linux

Comment détecter et résoudre les fuites de mémoire sous Linux

WBOY
WBOYavant
2024-02-12 14:30:17876parcourir

La fuite de mémoire fait référence au phénomène selon lequel le programme demande de l'espace mémoire mais ne le libère pas à temps pendant le processus en cours, ce qui entraîne une occupation de plus en plus importante de la mémoire, voire un crash du système. Les fuites de mémoire sont un défaut logiciel courant et constituent un problème qui ne peut être ignoré pour les systèmes Linux. Alors, comment trouver et réparer les fuites de mémoire sous Linux ? Quels outils peuvent nous aider à détecter et analyser les fuites de mémoire ? Cet article vous présentera plusieurs outils de fuite de mémoire couramment utilisés sous Linux, vous permettant de mieux gérer et optimiser les ressources mémoire sous Linux.

Linux 下如何检测和解决内存泄漏问题

Les fuites de mémoire peuvent être divisées dans les catégories suivantes :
1. Fuites de mémoire fréquentes. Le code présentant des fuites de mémoire sera exécuté plusieurs fois, provoquant une fuite de mémoire à chaque exécution.
2. Fuites de mémoire sporadiques. Le code provoquant des fuites de mémoire ne se produira que dans certaines circonstances ou opérations. Les cas fréquents et sporadiques sont relatifs. Dans certaines circonstances, ce qui est occasionnel peut devenir courant. L’environnement de test et les méthodes de test sont donc cruciaux pour détecter les fuites de mémoire.
3. Fuite de mémoire unique. Le code qui provoque une fuite de mémoire ne sera exécuté qu'une seule fois, ou en raison de défauts algorithmiques, il y aura toujours une et un seul bloc de mémoire divulgué. Par exemple, la mémoire est allouée dans le constructeur d’une classe Singleton, mais la mémoire n’est pas libérée dans le destructeur. Il n’existe qu’une seule instance de la classe Singleton, la fuite de mémoire ne se produira donc qu’une seule fois.
4. Fuite de mémoire implicite. Le programme alloue continuellement de la mémoire pendant son exécution, mais ne libère la mémoire qu'à la fin. À proprement parler, il n’y a pas de fuite de mémoire ici, car le programme finit par libérer toute la mémoire demandée. Mais pour un programme serveur qui doit fonctionner pendant des jours, des semaines, voire des mois, le fait de ne pas libérer de mémoire à temps peut également conduire à l'épuisement éventuel de toute la mémoire du système. Par conséquent, nous appelons ce type de fuite de mémoire une fuite de mémoire implicite.

Outil de détection de fuite de mémoire

Il existe de nombreuses façons de détecter les fuites de mémoire. Voici une liste des outils de détection de fuite de mémoire couramment utilisés sous Linux.

1, mtrace

Environnement d'application : Linux GLIBC

Langage de programmation : C

Utilisation : incluez le fichier d'en-tête mcheck.h, définissez la variable d'environnement MALLOC_TRACE comme nom du fichier de sortie et appelez mtrace() au démarrage du programme.

Sortie du résultat : fichier spécifié par l'utilisateur

Idée de conception : ajoutez des fonctions de hook aux fonctions malloc, realloc et free, et enregistrez l'exécution de chaque paire sans malloc

Avantages et inconvénients : seules les fuites de mémoire causées par l'utilisation de malloc/realloc/free peuvent être vérifiées

Comment l'obtenir : GLIBC est fourni avec et peut être utilisé directement

2.memwatch

Environnement d'application : Linux

Langage de programmation : C

Instructions : Ajoutez memwatch.h, ajoutez -DMEMWATCH -DMW_STDIO et memwatch.c lors de la compilation

Sortie du résultat : le nom du fichier de sortie est memwatch.log Pendant l'exécution du programme, des invites d'erreur seront affichées sur stdout

.

Idée de conception : redéfinir malloc/realloc/calloc/strdup/free, etc. en tant que mwMalloc(sz, FILE, LINE), etc., et maintenir une liste chaînée d'opérations en interne

Avantages et inconvénients : peut détecter la mémoire doublement libre, libre par erreur, non libérée, le débordement, le sous-débordement, etc.

Comment l'obtenir : http://memwatch.sourceforge.net/

3.valgrind

Environnement d'application : Linux

Langage de programmation : C/C++

Comment l'utiliser : ajoutez l'option -g lors de la compilation, telle que gcc -g filename.c -o filename, et utilisez la commande suivante pour détecter l'utilisation de la mémoire :

Résultat : #valgrind –tool=memcheck –leak-check=yes –show-reachable=yes ./filename, vous verrez le rapport d'utilisation de la mémoire

Idée de conception : conserver une table d'espace d'adressage valide et une table d'espace d'adressage invalide (espace d'adressage du processus) en fonction du fonctionnement de la mémoire du logiciel

Avantages et inconvénients : Capacité de détection :

  • Utilisation de la mémoire non initialisée
  • Utiliser la mémoire libérée (Lecture/écriture de la mémoire après sa libération)
  • Utiliser plus d'espace mémoire que celui alloué par malloc (lecture/écriture de la fin des blocs mallocés)
  • Accès illégal à la pile (Lecture/écriture de zones inappropriées sur la pile)
  • Si l'espace appliqué a été libéré (fuites de mémoire – où les pointeurs vers les blocs mallocés sont perdus à jamais)
  • Utilisation incompatible de malloc/new/new [] vs free/delete/delete [])
  • Chevauchement des pointeurs src et dst dans memcpy() et fonctions associées)
  • Répétez gratuitement

Comment obtenir : http://valgrind.org/

4.debug_new

Environnement d'application : Linux/Windows

Langage de programmation : C++

Instructions : Incluez le fichier d'en-tête debug_new.h, lien debug_new.cpp

Sortie du résultat : console

Idée de conception : capturez les demandes d'application/libération de mémoire en surchargeant les opérateurs new et delete, et maintenez une liste de hachage de variables statiques globales à l'intérieur du programme. Dans l'opérateur new, il alloue non seulement la mémoire demandée par l'utilisateur, mais ajoute également un en-tête à chaque mémoire allouée, qui stocke les informations d'emplacement et le pointeur de liste chaînée de l'allocation. New renvoie la valeur du bloc alloué. décalage de tête dans la mémoire, et cette valeur de retour a été calculée par HASH auparavant et ajoutée à la liste chaînée HASH. Lors de la suppression, effectuez d'abord un calcul HASH en fonction de l'adresse du pointeur à libérer, puis parcourez la liste chaînée à la valeur HASH du tableau pour rechercher. S'il est trouvé, le nœud sera supprimé. S'il n'est pas trouvé, il sera abandonné. De cette façon, une fois le programme terminé, vérifiez s'il existe des blocs de mémoire non libérés dans ce tableau pour déterminer s'il y a une fuite de mémoire.

Avantages et inconvénients : multiplateforme, uniquement pour les programmes C++,

Comment l'obtenir : http://www.ibm.com/developerworks/cn/linux/l-mleak2/index.html

Résumé

Les méthodes utilisées par les outils d'analyse ci-dessus peuvent être grossièrement divisées dans les catégories suivantes :

1. Enregistrez la fonction d'allocation de mémoire/libération du crochet (hook). Sous Linux, il existe cinq fonctions de hook telles que malloc_hook et free_hook. Sous Windows, vous pouvez enregistrer la fonction de hook _CrtSetAllocHook, afin que cette requête puisse être capturée et traitée lorsque la mémoire est allouée. Visual Leak Detecter et mtrace utilisent cette méthode.

2. Utilisez le remplacement de définition de macro. Remplacez malloc et free dans le code utilisateur par des fonctions personnalisées telles que mwMalloc(sz, FILE, LINE) définies par macro pour suivre les demandes de mémoire.

3. Surcharge de l'opérateur. Cette méthode n'est utilisée que dans le langage C++. Elle implémente le suivi des requêtes mémoire en surchargeant les opérateurs new et delete. Les opérateurs surchargés sont similaires à la signification des fonctions hook. debug_new adopte cette approche.

Les méthodes de sortie de ces outils sont également divisées dans les types suivants :

1. Dans des circonstances normales, la sortie est généralement envoyée vers la fenêtre de débogage. De nombreux logiciels offrent eux-mêmes un emplacement de sortie idéal, et la sortie des applications GUI vers la sortie standard n'est pas visible. Visual Leak Detecter utilise cette méthode.

2. Sortie vers la sortie standard ou la sortie d'erreur standard : les applications console peuvent afficher à l'écran, telles que memwatch, valgrind et debug_new, toutes utilisent cette méthode.

3. Sortie dans un fichier journal : affichez les résultats dans des fichiers journaux spécifiés par l'utilisateur ou par défaut, tels que mtrace et memwatch.

De plus, les méthodes de détection de mémoire de ces outils sont divisées en deux types :

1. Conserver une liste chaînée d'opération de mémoire Lorsqu'il y a une opération d'application de mémoire, elle est ajoutée à cette liste chaînée. Lorsqu'il y a une opération de libération, elle est supprimée de la liste chaînée de l'opération d'application. S'il y a encore du contenu dans la liste chaînée après la fin du programme, cela signifie qu'il y a une fuite de mémoire ; si l'opération de mémoire à libérer ne trouve pas l'opération correspondante dans la liste chaînée, cela signifie qu'elle a été libérée plusieurs fois ; . Utilisez cette méthode avec les outils de débogage intégrés, Visual Leak Detecter, mtrace, memwatch, debug_new.

2. Simulez l'espace d'adressage du processus. Modélisant la façon dont le système d'exploitation gère les opérations de mémoire de processus, un mappage d'espace d'adressage est maintenu en mode utilisateur. Cette méthode nécessite une compréhension approfondie du traitement de l'espace d'adressage de processus. Étant donné que la distribution de l'espace d'adressage du processus de Windows n'est pas open source, elle est difficile à simuler et n'est donc prise en charge que sous Linux. Celui qui adopte cette approche est valgrind.

Grâce à cet article, vous devriez avoir une compréhension de base du problème de fuite de mémoire sous Linux, et connaître ses causes, ses effets et ses solutions. Vous avez également découvert plusieurs outils de fuite de mémoire couramment utilisés sous Linux, tels que Valgrind, Memwatch, Mtrace, etc., ainsi que leurs méthodes d'utilisation, leurs avantages et leurs inconvénients. Nous vous recommandons d'utiliser ces outils pour détecter et analyser les fuites de mémoire lors du développement et du test de programmes Linux afin d'améliorer les performances et la stabilité des programmes. Parallèlement, nous vous rappelons également de faire attention à certaines précautions et restrictions lors de l'utilisation de ces outils afin d'éviter des erreurs d'appréciation ou des omissions. J'espère que cet article pourra vous aider à mieux utiliser le système Linux et vous permettre d'écrire des programmes de haute qualité sous Linux.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer