J'ai l'impression que les développeurs parlent de fuites de mémoire mais quand vous leur demandez ce que cela signifie beaucoup n'ont aucune idée. Pour prévenir ces situations, décidons d'un.
S'il vous plaît pas de définitions Wikipedia ...
Quelle est votre meilleure définition d'A fuite de mémoire et quel est le meilleur moyen pour les empêcher?
Il y a deux définitions (au moins pour moi):
Définition naïf : Défaut de libération la mémoire inaccessible , qui ne peut plus être attribuée à nouveau par aucun processus lors de l'exécution du processus d'allocation . Cela peut surtout être guéri en utilisant des techniques de GC (collecte des ordures) ou détectées par des outils automatisés.
définition subtile : Défaut de libération Mémoire accessible qui n'est plus nécessaire pour que votre programme fonctionne correctement. Ceci est presque impossible à détecter avec des outils automatisés ou des programmeurs qui ne connaissent pas le code. Bien que techniquement, ce n'est pas une fuite, il a les mêmes implications que la naïve. Ce n'est pas ma propre idée seulement. Vous pouvez rencontrer des projets qui sont écrits dans une langue collectée à la poubelle mais mentionnent toujours la fixation de fuites de mémoire dans leurs changelogs.
Définition: Échec de la libération de la mémoire après répartition.
Le processus dans lequel des ressources de mémoire sont allouées et non correctement libérées une fois que cela n'est plus nécessaire, souvent introduit par mauvaises pratiques de codage.
Certaines langues sont construites dans certaines langues pour les empêcher de les empêcher, bien que la meilleure façon de les éviter soit de l'observation diligente des chemins d'exécution du code et des critiques de code. Garder des méthodes courtes et singulièrement utiles aide à maintenir l'utilisation des ressources serrées et moins enclinées pour se perdre dans le shuffle.
En informatique, une fuite de mémoire est un type particulier de consommation de mémoire involontaire par un programme informatique où le programme ne parvient pas à libérer la mémoire lorsqu'il n'est plus nécessaire. Cette condition est normalement le résultat d'un bogue dans un programme qui l'empêche de libérer de la mémoire qu'elle ne nécessite plus.
La mémoire qui n'est pas traitée quand elle n'est plus nécessaire et n'est plus "accessible". Par exemple, dans le code non géré, si j'utilise "nouveau" pour instancier un objet, mais je n'utilise pas "Supprimer" lorsque j'en ai fini avec elle (et mon pointeur est passé de portée ou quelque chose).
La meilleure façon de les empêcher, dépend probablement de qui vous demandez et de quelle langue vous utilisez. La collection de la poubelle est une bonne solution pour cela, bien sûr, mais il peut y avoir des frais généraux associés à cela, ce qui n'est pas une grosse affaire à moins que votre performance soit votre principale préoccupation. La collecte des ordures peut ne pas toujours être disponible, à nouveau, en fonction de la langue que vous utilisez.
Sinon, vous pouvez vous assurer que vous disposez des suppresseurs et/ou des destructeurs appropriés en place. Il y a aussi beaucoup de méthodes et d'outils pour détecter des fuites de mémoire, mais cela dépendra de la langue et/ou de IDE vous utilisez.
Il y a deux manières qu'une fuite de mémoire peut être définie.
Premièrement, si les données ne sont pas libérées lorsqu'il n'y a plus aucune référence à ce sujet, ces données sont inaccessibles (sauf si vous avez du pointeur corrompu ou que vous avez déjà passé les données dans un tampon ou quelque chose). Fondamentalement, si vous ne libérez pas/supprimez les données allouées sur le tas, il devient inutilisable et gaspille simplement la mémoire.
Il peut y avoir des cas où un pointeur est perdu, mais les données sont toujours accessibles. Par exemple, si vous stockez le pointeur dans un INT ou stockez un décalage sur le pointeur (à l'aide de l'arithmétique du pointeur), vous pouvez toujours récupérer le pointeur d'origine.
Dans cette première définition, les données sont traitées par des collecteurs de déchets, qui gardent une trace du nombre de références aux données.
Deuxièmement, la mémoire est essentiellement fuite si elle n'est pas libérée/supprimée lors de la dernière utilisation. Il peut être référencé et immédiatement libre, mais l'erreur a été faite de ne pas le faire. Il peut y avoir une raison valable (par exemple dans le cas où un destructeur a un effet secondaire étrange), mais cela indique une mauvaise conception de programmes (à mon avis).
Ce deuxième type de fuite de mémoire se produit souvent lors de l'écriture de petits programmes utilisant le fichier IO. Vous ouvrez le fichier, écrivez vos données, mais ne le fermez pas une fois que vous avez terminé. Le fichier * peut toujours être dans la portée et facilement restreinte. Encore une fois, il peut y avoir une raison quelconque de cela (comme l'accès en écriture de verrouillage par d'autres programmes), mais pour moi, c'est un drapeau de mauvais design.
Dans cette deuxième définition, les données ne sont pas manipulées par des collecteurs de déchets, à moins que le compilateur/interprète soit suffisamment intelligent (ou stupide) pour savoir qu'elle ne sera plus utilisée, et cela libérant les données ne causera aucun effet secondaire.
Fuite de mémoire: Échec de la mémoire libre que vous n'avez plus besoin avant de:
meilleur moyen d'empêcher les fuites de mémoire: mémoire libre dès qu'il n'est plus nécessaire.
Toutes les définitions données ici (à l'époque où j'ai écrit cela, nous avons obtenu de meilleures réponses depuis) omettre d'abord d'aborder une affaire limite:
Vous avez un singleton qui alloue la mémoire lors de la création et que cette mémoire est normalement détenue tant que le programme fonctionne même si l'utilisation actuelle est effectuée et qu'il est inconnu si une utilisation future sera effectuée ou non. Cela se fait généralement à cause des frais généraux de la recréer.
Par "Échec à libérer lorsqu'il est fait avec elle" standard, cela serait considéré comme une fuite et que j'ai vu des outils de déclaration de fuites appelle de telles choses qui fuient que la mémoire était toujours utilisée. (Et en fait, le code peut ne pas contenir de code capable de nettoyer l'objet.)
Cependant, j'ai rencontré du code de cette nature dans les bibliothèques de compilateur avant même que le coût de recréer l'objet n'est pas tout ce qui est génial.
Fuites ou pas?
Voici quelques techniques pour prévenir/détecter des fuites de mémoire:
Considérez votre algorithme en termes de consommation de mémoire. Autres répondants ont mentionné le fait que vous n'avez pas à perdre le pointeur à un objet alloué pour fuir la mémoire. Même si votre implémentation contient Zero Pointer Bugs, vous pouvez toujours résoudre efficacement la mémoire si vous maintenez des articles alloués longtemps après avoir besoin d'eux.
Profil de votre application. Vous pouvez utiliser des outils de débogueur de mémoire comme Valgrind ou purifier pour trouver des fuites.
Test de boîte noire. Regardez ce qui arrive à votre code compilé après avoir alimenté les grands ensembles de données, ou laissez-la fonctionner pendant de longues périodes. Voyez si son encombrement de mémoire a tendance à se développer sans limite.