11
votes

Quand une fuite de mémoire peut-elle se produire?

Je ne sais pas quoi penser ici ...

Nous avons un composant qui fonctionne comme service. Il fonctionne parfaitement sur ma machine locale, mais sur une autre machine (sur les deux RAM de la machine est égale à 2 Go), il commence à générer des exceptions Bad_ALLOC sur la deuxième et les jours consécutifs. La chose est que l'utilisation de la mémoire du processus reste la même au niveau précotionnellement de 50 Mo. L'autre chose étrange est que, à l'aide de messages de traçage, nous avons localisé l'exception à projeter à partir d'un objet StringStream, mais n'insérez pas plus de 1-2 Ko dans le flux. Nous utilisons STL-Port si cela importe.

Maintenant, lorsque vous obtenez une exception BAD_ALLOC, vous pensez que c'est une fuite de mémoire. Mais tous Nos allocations manuelles sont enveloppées dans un pointeur intelligent. De plus, je ne peux pas comprendre comment un objet de stringream manque de mémoire lorsque l'ensemble du processus utilise seulement ~ 50 Mo (l'utilisation de la mémoire reste approximativement constante (et certainement ne se lève pas) de jour en jour).

Je ne peux pas vous fournir de code, car le projet est vraiment gros, et la partie qui jette l'exception ne fait vraiment rien d'autre mais crée un stringream et << des données, puis de la connecter.

Alors, ma question est ... Comment une fuite de mémoire peut-elle se produire lorsque le processus utilise seulement 50 Mo de mémoire de 2 Go? Quelles autres suppositions sauvages avez-vous quant à ce qui pourrait être faux?

Merci d'avance, je sais que la question est vague, etc., je suis juste une sorte de désespéré et j'ai fait de mon mieux pour expliquer le problème.


3 commentaires

@skwllSP: Je ne peux tout simplement pas croire que la fragmentation de la mémoire pourrait entraîner une défaillance de la mémoire de 1 ~ 2kb lorsque seulement 50 Mo sont utilisés ... peut-il?


Si c'était une fragmentation, je ne peux pas comprendre pourquoi cela ne se produirait pas localement après assez de temps d'exécution. On dirait que la reproduction est spécifique à certaines caractéristiques de l'autre machine.


Lorsque vous le dites utilise seulement 50 Mo, voulez-vous dire que sa taille en mémoire ne dépasse jamais 50 Mo ou que ses allocations ne s'ajoutent pas à plus de 50 Mo? Un petit programme peut facilement allouer / libérer plus de mémoire qu'il utilise à tout moment et la collecte des ordures peut varier d'une machine à la machine.


8 Réponses :


1
votes

Juste un hunch,

mais j'ai eu des problèmes dans le passé lors de l'allocation de tableaux comme si tellement xxx

lorsque la taille est un grand nombre. < p> La solution consistait à allouer avec le nouvel opérateur XXX

J'ai trouvé cela très déroutant, la raison s'est avérée être le cadre de pile comme indiqué ici dans la solution de Martin York : existe une limite de longueur maximale de la matrice en C ++?

Tout le meilleur,

TOM


0 commentaires


6
votes

Une raison probable dans votre description est que vous essayez d'allouer un bloc de grande taille déraisonnablement en raison d'une erreur dans votre code. Quelque chose comme ceci; xxx

maintenant si numéros de choix est laissé ininitialisé, il peut contenir un nombre de manière déraisonnable et donc vous essayez efficacement d'allouer un bloc de 3 Go que la mémoire que la mémoire que la mémoire Le gestionnaire refuse de faire.

afin que votre programme soit court à la mémoire, mais qu'il essaie d'allouer plus de mémoire qu'il ne pouvait être autorisé à être inférieur à la meilleure condition.


0 commentaires


0
votes

Je ne vois pas pourquoi un flux lancerait. Vous n'avez pas de vidage du processus défaillant? Ou peut-être attacher un débogueur pour voir ce que l'allocator tente d'allouer?

Mais si vous avez surchargé l'opérateur <<< / code>, alors peut-être que votre code a un bogue.

juste mon 2 (euro) cts ...

1. Fragmentation?

La mémoire pourrait être fragmentée.

À un moment donné, vous essayez d'allouer des octets de taille, mais l'allocator ne trouve pas de morceaux de taille contigus d'octets en mémoire, puis jetez un Bad_ALLOC.

NOTE: Cette réponse a été écrite avant de lire cette possibilité a été exclue.

2. Signé vs. non signé?

Une autre possibilité serait l'utilisation d'une valeur signée pour la taille à attribuer: xxx

si la valeur du code i est négatif (par exemple -1), la distribution dans l'intégral non signé Taille_t va aller au-delà de ce qui est disponible pour l'allocator mémoire.

comme le L'utilisation de l'intégrale signée est assez courante dans le code de l'utilisateur, si seulement doit être utilisée comme valeur négative pour une valeur non valide (par exemple -1 pour une recherche échouée), il s'agit d'une possibilité.


0 commentaires

0
votes

Un autre coup long: vous ne dites pas dans lequel des trois opérations l'erreur se produit (construction, <<< / code> ou journal), mais le problème peut être une fragmentation de la mémoire, plutôt que la consommation de mémoire. Peut-être que Stringstream ne trouve pas assez de bloc de mémoire contiguë pour tenir un couple de Ko.

Si tel est le cas, et si vous exercez cette fonction le premier jour (sans MISH), vous pourriez faire la chaîne une variable statique et la réutiliser. Autant que je sache que StringStream ne compromet pas son espace tampon au cours de sa vie, alors s'il établit un gros tampon le premier jour, il continuera de l'avoir à partir de ce moment (pour une sécurité supplémentaire, vous pourriez exécuter une ficelle factice de 5 Ko lorsque Il est d'abord construit).


0 commentaires

-1
votes

À titre d'exemple, des fuites de mémoire peuvent se produire lorsque vous utilisez l'opérateur Nouveau en C ++ et oubliez d'utiliser l'opérateur Supprimer .

ou, en d'autres termes, lorsque vous allouez un bloc de mémoire et que vous oubliez de le distribuer.


0 commentaires

0
votes
 ~className(){

 //delete stuff in here

}

0 commentaires