49 votes

Comment résoudre la fragmentation de la mémoire

Nous avons parfois eu des problèmes de laquelle notre serveur en cours d'exécution des processus (en cours d'exécution sur Windows Server 2003) ont lancé une exception en raison d'un échec d'allocation de mémoire. Nos soupçons sont ces allocations sont échoue en raison d'une fragmentation de la mémoire.

Par conséquent, nous avons été à la recherche à certains autres mécanismes d'allocation mémoire qui peut nous aider et je suis en espérant que quelqu'un peut me dire le meilleur:

1) l'Utilisation de Windows à Faible fragmentation du Tas

2) jemalloc - utilisé dans Firefox 3

3) Doug Lea malloc

Notre processus serveur est développé à l'aide de la croix-plate-forme de code C++, de sorte que toute solution serait idéalement de la croix-plate-forme (ne *nix systèmes d'exploitation souffrent de ce type de fragmentation de la mémoire?).

Aussi, suis-je en droit de penser que LFH est maintenant par défaut mécanisme d'allocation de mémoire pour Windows Server 2008 / Vista?... Mes problèmes actuels "go away" si nos clients n'ont qu'à mettre à niveau leur système d'exploitation serveur?

38voto

Tall Jeff Points 6065

Tout d'abord, je suis d'accord avec les autres posters, qui a suggéré une fuite de ressources. Vous voulez vraiment de règle que le premier.

Heureusement, le gestionnaire de tas que vous utilisez actuellement est un moyen de vider le total réel de l'espace libre disponible dans le tas (dans tous les gratuit blocs) et aussi le nombre total de blocs qu'il est réparti sur. Si la moyenne bloc libre de taille est relativement petite par rapport à l'ensemble de l'espace libre dans le tas, alors tu as un problème de la fragmentation. Alternativement, si vous pouvez faire un dump de la taille du plus grand bloc et de les comparer à l'espace libre total, qui va accomplir la même chose. Le plus grand bloc serait faible par rapport au nombre total libre de l'espace disponible dans tous les blocs si vous êtes en cours d'exécution dans la fragmentation.

Pour être très clair sur le dessus, dans tous les cas, nous parlons de libre - blocs dans le tas, pas les blocs alloués dans le tas. En tout cas, si les conditions ci-dessus ne sont pas remplies, vous ne disposez d'une situation de fuite de quelque sorte.

Donc, une fois que vous avez exclu une fuite, vous pourriez envisager d'utiliser une meilleure allocation. Doug Lea malloc suggérée dans la question est un très bon programme d'allocation pour l'utilisation générale des applications et très robuste, la plupart du temps. Mettre une autre manière, il a été testé pour fonctionner très bien pour la plupart des applications. Cependant, aucun algorithme est idéal pour toutes les applications et toute l'algorithme de gestion de l'approche peut être rompu par le droit pathelogical conditions à l'encontre de son design.

Pourquoi êtes-vous eu un problème de la fragmentation? - Les Sources de la fragmentation des problèmes sont causés par le comportement d'une application et d'avoir à faire avec très différente de l'allocation de vie dans le même mémoire de l'arène. C'est, certains objets sont alloués et libéré régulièrement alors que d'autres types d'objets persister pendant de longues périodes de temps, tous dans le même tas.....pensez à la durée de vie plus longue que piquer des trous dans les grandes zones de l'arène et de prévenir ainsi l'fusionner des blocs adjacents qui ont été libérés.

Pour résoudre ce type de problème, la meilleure chose que vous pouvez faire est de diviser logiquement le tas en sous arènes où les durées de vie sont de plus en plus semblables. En effet, vous voulez un transitoire tas et persistante des tas, des tas groupe de choses de semblable durée de vie.

D'autres ont proposé une autre approche pour résoudre le problème qui consiste à tenter de faire la répartition des tailles de plus en plus semblables ou identiques, mais cela est moins idéale, car il crée un autre type de fragmentation interne à la fragmentation de ce qui est en effet le gaspillage de l'espace que vous avez en allouer plus de mémoire dans le bloc que vous avez besoin.

En outre, avec un bon tas de allocateur, comme Doug Lea, faisant de la taille des blocs de plus en plus semblables est inutile parce que l'allocateur va déjà faire une puissance de deux la taille de l'écopage plan de le rendre totalement inutile d'ajuster artificiellement la répartition des tailles passé à la fonction malloc () en effet, son gestionnaire de tas fait pour vous automatiquement beaucoup plus robuste que l'application sera en mesure de faire des ajustements.

15voto

Tal Points 617

Je pense que vous avez tort d'exclure une fuite de mémoire trop tôt. Même une petite fuite de mémoire peut provoquer une forte fragmentation de la mémoire.

En supposant que votre application se comporte comme suit:
Allouer 10 MO
Allouer 1 octet
Gratuit 10 MO
(oops, nous n'avons pas libre le 1 octet, mais qui se soucie de 1 petit octets)

Cela semble être une très petite fuite, vous aurez du mal à le remarquer lors de la surveillance du total alloué à la taille de la mémoire. Mais cette fuite finira par causer à votre application de mémoire pour ressembler à ceci:
.
.
Gratuit – de 10 mo
.
.
[Alloué -1 octet]
.
.
Gratuit – de 10 mo
.
.
[Alloué -1 octet]
.
.
Gratuit – de 10 mo
.
.

Cette fuite ne sera pas remarqué... jusqu'à ce que vous souhaitez allouer 11MO
En supposant que votre les minidumps avait plein de mémoire d'infos compris, je vous recommande d'utiliser DebugDiag pour repérer les éventuelles fuites. Dans le générés rapport de mémoire, d'examiner attentivement le nombre d'allocations (pas de taille).

5voto

Mark Points 6505

Comme vous le suggérez, Doug Lea malloc pourrait bien fonctionner. Il est multi-plateforme et il a été utilisé dans le code de la navigation. À tout le moins, il devrait être facile à intégrer dans votre code pour les tests.

Ayant travaillé dans la mémoire fixe environnements pour un certain nombre d'années, cette situation est certainement un problème, même dans des environnements. Nous avons trouvé que la CRT allocateurs ont tendance à puer assez mauvais en terme de performances (vitesse, l'efficacité de l'espace perdu, etc). Je crois fermement que si vous avez des besoin d'un bon programme d'allocation de mémoire sur une longue période de temps, vous devriez écrire votre propre (ou voir si quelque chose comme dlmalloc de travail). L'astuce est de trouver quelque chose d'écrit, qui fonctionne avec les modèles d'allocation, et qui a plus à voir avec la gestion de la mémoire de l'efficacité que n'importe quoi d'autre.

Donner dlmalloc un essai. J'ai certainement donner un coup de pouce. Il est assez accordable, de sorte que vous pourriez être en mesure d'obtenir plus d'efficacité par le changement de certains de la durée de la compilation des options.

Honnêtement, vous ne devriez pas compter sur les choses "s'en aller" avec le nouveau système d'exploitation mises en œuvre. Un service pack, un patch ou un autre nouvel OS N années plus tard pourrait aggraver le problème. Encore une fois, pour des applications qui requièrent une solide gestionnaire de mémoire, n'utilisez pas le stock versions sont disponibles avec votre compilateur. En trouver un qui fonctionne pour votre situation. Commencez avec dlmalloc et la paramétrer pour voir si vous pouvez obtenir le comportement qui fonctionne le mieux pour votre situation.

2voto

Fire Lancer Points 8934

Vous pouvez aider à réduire la fragmentation en réduisant le montant que vous allouer désallouer.

par exemple dire que pour un serveur web qui exécute un serveur de script côté, il peut créer une chaîne de sortie la page pour. Au lieu d'affectation et deallocting ces chaînes pour chaque demande de page, simplement de maintenir un pool d'entre eux, de sorte que votre seule allocation lorsque vous avez besoin de plus, mais de ne pas le libérer (sens après un certain temps, vous obtenez la situation que vous ne pas allouer plus non plus, parce que vous avez assez d')

Vous pouvez utiliser _CrtDumpMemoryLeaks(); pour vider mémorables fuites dans la fenêtre de débogage lors de l'exécution d'une version de débogage, mais je crois que c'est percific pour le Visual C compilateur. (son crtdbg.h)

1voto

nsanders Points 5282

Je soupçonne une fuite avant de soupçonner une fragmentation.

Pour les structures de données gourmandes en mémoire, vous pouvez passer à un mécanisme de pool de stockage réutilisable. Vous pourriez également être en mesure d’allouer plus de matériel sur la pile plutôt que sur le tas, mais dans la pratique, cela ne fera pas une énorme différence, je pense.

Je lancerais un outil comme Valgrind ou ferais une journalisation intensive pour rechercher les ressources non libérées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X