Je ne sais pas quoi penser ici ... P>
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. P>
Maintenant, lorsque vous obtenez une exception BAD_ALLOC, vous pensez que c'est une fuite de mémoire. Mais tous em> strong> 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). P>
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. p>
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? P>
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. p>
8 Réponses :
Juste un hunch,
mais j'ai eu des problèmes dans le passé lors de l'allocation de tableaux comme si tellement p> lorsque la taille est un grand nombre. P> < p> La solution consistait à allouer avec le nouvel opérateur p> 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 ++? P> Tout le meilleur, P> TOM P> P>
Vérifiez le profil d'autres processus de la machine à l'aide de Explorateur de processus de Sysinternals - vous obtiendrez Vérifiez votre propre utilisation de la mémoire à l'aide de UMDH A > Pour obtenir des instantanés et comparer le profil d'utilisation au fil du temps. Vous devrez le faire tôt dans le cycle pour éviter d'explorer l'outil, mais si le comportement de votre processus ne se dégrade pas dans le temps (c.-à-d. Pas de comportement pathologique soudain), vous devez obtenir des informations précises sur son utilisation de la mémoire à l'heure Bad_alloc CODE> si la mémoire est courte, même si ce n'est pas vous qui provoque une pression de mémoire. P>
T code> vs temps
t + t code>. P>
Explorateur de processus Affiche Taille virtuelle Code> Parmi les autres statistiques détaillées par processus - si un ou plusieurs processus sont gourmands, il vous le dira.
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; maintenant si 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. P> p> numéros de choix code> 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. p>
Vous pouvez également utiliser Valgrind ou l'un de ses Remplacements de Windows pour trouver la fuite / dépassement. P> Bad_alloc code> ne signifie pas nécessairement qu'il n'y a pas assez de mémoire. Les fonctions d'allocation peuvent également échouer car le tas est corrompu. Vous pourriez avoir un certain dépassement de tampon ou de l'écriture de code dans la mémoire supprimée, etc. p>
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 juste mon 2 (euro) cts ... p> La mémoire pourrait être fragmentée. P> À 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. P> NOTE: Cette réponse a été écrite avant de lire cette possibilité a été exclue. i> p> Une autre possibilité serait l'utilisation d'une valeur signée pour la taille à attribuer: p> si la valeur du code 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é. P> P> <<< / code>, alors peut-être que votre code a un bogue. P>
1. Fragmentation? H2>
2. Signé vs. non signé? h2>
i code> est négatif (par exemple -1), la distribution dans l'intégral non signé
Taille_t code> va aller au-delà de ce qui est disponible pour l'allocator mémoire. P>
Un autre coup long: vous ne dites pas dans lequel des trois opérations l'erreur se produit (construction, 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). P> <<< / 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. P>
À titre d'exemple, des fuites de mémoire peuvent se produire lorsque vous utilisez l'opérateur ou, en d'autres termes, lorsque vous allouez un bloc de mémoire et que vous oubliez de le distribuer. P> Nouveau code> en C ++ et oubliez d'utiliser l'opérateur
Supprimer code>. p>
~className(){ //delete stuff in here }
@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 i> 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.