11
votes

OutofMemory, mais pas de GCROTS pour de nombreux objets

Nous développons une application de formulaires Windows assez importante. Dans plusieurs ordinateurs de clients, il se bloque souvent avec une exception exceptionnelle. Après avoir obtenu le dépotoir de la mémoire complète des moments d'application après l'exception (clrdump invoqué à partir du manutentionnaire non gourde), je l'ai analysé avec «Profileur de mémoire .NET» et WINDBG.

Le profileur de mémoire n'a montré que 130 Mo dans des instances d'objet en direct. Ce qui est intéressant, c'est que, pour de nombreux types d'objets, on a montré un très grand nombre d'instances inaccessibles (par exemple 22000 des instances d'octets inaccessibles). Dans les statistiques de la mémoire native, il totalise 127 Mo dans tous les tas pour les données (ce qui est correct), mais indique 133 Mo inaccessible dans le tas n ° 2 en tas et 640 Mo dans un grand tas (pas OK!). P>

Lorsque vous analysez le dépotoir avec WINDBG, les statistiques ci-dessus sont confirmées: p> xxx pré>

L'application utilise un grand nombre de tampons courts à travers son temps d'exécution, mais ne les fuit pas. Test de plusieurs des octets [] avec! GCROOT finit sans racines. Évidemment, la plupart de ces matrices sont inaccessibles comme indiqué par le profileur de mémoire. P>

Juste pour vous assurer que tout va bien,! Finalizequeue montre qu'aucun objet n'attend d'être finalisé P>

generation 0 has 138 finalizable objects (18bd1938->18bd1b60)
generation 1 has 182 finalizable objects (18bd1660->18bd1938)
generation 2 has 75372 finalizable objects (18b87cb0->18bd1660)
Ready for finalization 0 objects (18bd1b60->18bd1b60)


0 commentaires

4 Réponses :


4
votes

5 commentaires

Les tampons varient de 20k à quelques Mo et sont généralement créés par un fournisseur de base de données pour charger la forme de données DB ou par un code qui le remplit ensuite avec des données à partir de la prise (la taille des données est connue, les tampons sont donc définis avec la taille correcte, pas grandir)


Sont-ils connus de taille au moment de l'exécution ou du temps de design? On dirait que vous devrez trouver un moyen de les réutiliser.


La taille est déterminée au moment de l'exécution - les tampons Stocker Email Mime Pièces, de sorte que chaque tampon diffère de taille. Nous pouvons tenter de réutiliser nos propres tampons, mais il y a aussi les tampons du fournisseur. Mais oui, au moment où nous devrons essayer de réutiliser une partie du tampon. Bien que cela ne repasse que le problème, je crois ..


Grepfruit, c'est un territoire paradoxal. Il peut payer pour atteindre les allocations UP (allouer 1 Mo lorsque vous avez besoin de 85 Ko et 1 Mo). Vous pouvez également poster une question plus spécifique ici (comment optimiser le TOP pour LOH).


La chose est que je ne suis toujours pas tout à fait sûr que ceci est une fragmentation de LOH, ou que ce n'est toujours qu'un problème. Ce qui me dérange, c'est le fait que tant d'objets sur le Loh sont irréguliers, mais ils ne sont pas marqués comme espace libre. Depuis de ce que j'ai lu pour Gen n ° 2 et Loh, une collection de déchets complète est toujours effectuée - il devrait donc y avoir un minimum d'objets non référencés en supposant que ce soit juste avant que la collection OOM a été effectuée.



1
votes

Parfois Image.Fromfile ("Un fichier non image") jette une exception exceptionnelle. Un fichier d'octet zéro est un tel fichier qui sera.


1 commentaires

Merci pour l'information, nous avons déjà vécu cette question aussi, alors bon point. Cependant, à ce moment, l'OMM est lancé lors d'une allocation, alors il n'ya probablement pas assez d'espace continu.



2
votes

Comme généralement, les choses se sont avérées peu différentes. Nous avons trouvé une upease où la demande a consommé beaucoup de mémoire et finirait par aller Oom. Qu'est-ce qui était étrange dans les décharges que nous avons obtenus avant que nous ayons trouvé que c'était qu'il y avait beaucoup d'objets sans GCroot - je n'ai pas compris pourquoi ce n'était-il pas libéré et utilisé pour de nouvelles allocations? Ensuite, il est venu à moi que ce qui s'est probablement passé lorsque l'OMM s'est produite - la pile était déroulée et les objets qui possédaient la mémoire n'étaient plus accessibles et que le décharge a ensuite été effectué. C'est pourquoi c'est pourquoi il semblait beaucoup de mémoire qui pourrait être grev.

Qu'est-ce que j'ai fait dans une version de débogage - pour récupérer véritable vive-de-la-mémoire - est de créer un filetage. La minuterie qui vérifie si un objet raisonnablement important pourrait être attribué - s'il ne peut pas être attribué, c'est une indication que nous sommes proches de l'OOM et que son bon moment pour prendre la mémoire de mémoire. Le code suit: xxx


0 commentaires

1
votes

Si vous pensez que LOH est le problème, alors avoir un point de pause sur l'allocation de LOH pourrait vous indiquer dans la bonne direction. Vous pourriez probablement faire quelque chose comme ça

BP MSCORWKS! GC_HEAP :: Allocate_Large_Object "! CLROSTACK; .CHO ********* Allocation de grand heap objet **********; g"


0 commentaires