2009-06-10 8 views
7

J'ai une application WPF qui affiche entre autres beaucoup d'images, grandes et petites. Mon problème est que l'application utilise beaucoup de mémoire et je n'arrive pas à comprendre d'où elle vient.où est passé mon souvenir? grand nombre d'octets privés

Le scénario, en insistant sur l'application certains je reçois ce graphique dans perfmon:

http://www.imagechicken.com/uploads/1244548604007097000.jpg

La grande ligne noire est Processus \ octets privés et les autres lignes sont les compteurs mem CLR (le rose est nombre total d'octets) engagés

en chiffres du graphique sont:
octets privés ~ 350 Mb
octets ~ 100 Mb Committed

Je suis en train de creuser autour de beaucoup avec WinDbg et d'autres outils, et ils signalent tout ce que la pile géré se comporte (! Rapports de eeheap total géré pile d'environ 100 Mb)

J'ai farfouillé avec des applications comme LeakDiag, LDGrapher mais n'a rien trouvé.

Donc, finalement à ma question, comment puis-je procéder pour savoir où va ma mémoire?

Même en démarrant l'application utilise 100 Mo en octets validés mais 190 Mo en octets privés.

Références:

J'ai lu beaucoup à ce sujet, entre autres sur les grands sites:

Tess Ferrandez: http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx

Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx

MSDN mag: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx

+0

Merci pour les réponses à ce jour. Donc, pour clarifier,! Eeheap,! Dumpheap, gcroot etc. tous rapportent les choses qui composent le 100Mb - ce que j'essaie de me débarrasser de l'autre mémoire - les 250 Mo supplémentaires. – andyhammar

+0

Mise à jour - avec VADUMP: Rapports "Grand ensemble de travail total" de 236 Mo, "Autres données" comme 196 Mo. En attendant! Eeheap rapporte "taille de tas de GC" au 107336836. Quelle est cette différence? – andyhammar

+0

'Autres données' inclut le tas GC avec d'autres données :) Je ne suis pas sûr quoi d'autre est là, mais il est sûr de supposer que les données d'exécution requises par le CLR. –

Répondre

1

Télécharger MemProfiler de Scitech. Il a une version d'essai de 14 jours.

Le problème que vous signalez est souvent dû à des vues/ressources qui ne peuvent pas être éliminées en raison d'une racine dans le tas. Une cause commune n'est pas les gestionnaires d'événements non destructeurs.

+0

Merci Mitch. Juste joué avec MemProfiler un peu et trouvé beaucoup de byte [] de "MergedDictionaries" (une chose WPF). Essayer de réparer ça maintenant. Ce n'est pas tout mais quelque chose, merci! – andyhammar

3

Le fait que votre application utilise beaucoup de mémoire ne signifie pas forcément que vous avez une fuite de mémoire. D'après l'information contenue dans votre question, il est difficile d'affirmer ce qui pourrait être faux.

Lors de la résolution des fuites de mémoire gérées avec WinDbg je fais ce qui suit:

  • obtenir un aperçu de l'utilisation du tas avec !eeheap (ce rapporte l'utilisation du tas et non la pile que vous mentionnez - chaque pile a une taille par défaut de 1 Mo, donc à moins que vous ayez changé cela, vous ne pouvez pas utiliser 100 Mo sur la pile)

  • Faites un !dumpheap -stat pour savoir ce qui se trouve sur le tas. Les chances sont que si vous avez une fuite de mémoire le type coupable sera parmi les meilleurs consommateurs.Pour avoir une idée de l'évolution de l'utilisation du tas, vous pouvez reprendre votre application, la décomposer un peu plus tard, puis répéter la commande !dumpheap -stat.

  • Si vous trouvez des types avec plus d'instances que vous le feriez à l'exception, répertoriez celles qui utilisent !dumpheap -mt <MT of type>. Cela va lister toutes les instances du type particulier. Choisissez des instances aléatoires et vérifiez les racines à l'aide de la commande !gcroot. Cela vous dira ce qui maintient les instances en question en vie. S'il n'y a pas de racine, ces instances seront collectées à un moment donné.

UPDATE pour répondre à vos commentaires:

Le tas managé est seulement une partie de l'empreinte mémoire d'une application gérée. Rappelez-vous, qu'une application .NET est vraiment une application dans une autre application - le processus hôte, qui charge le CLR, qui à son tour charge votre application. Donc, avant que votre application commence à utiliser de la mémoire, le CLR a déjà pris une part équitable. En plus de cela, les applications .NET stockent à la fois le code MSIL et le code compilé JIT dans le cadre de l'empreinte. Le CLR prend également de la place pour diverses tâches de comptabilité (par exemple, le CLR crée deux AddDomains supplémentaires pour un usage interne).

Les chiffres que vous donnez ne me paraissent pas exagérés, mais comme je ne connais pas votre application, il est difficile de dire s'ils sont excessifs. 100 Mo sur le tas géré peut convenir, selon ce que fait votre application. Avez-vous vérifié le tas? Et si oui, qu'avez-vous trouvé?

+0

Merci Brian! Avec une taille de 139 596 684, mes plus grands utilisateurs sont: 1) System.Byte [] (14949 articles, mem: 32 217 996), 2) System.String (475 010 articles, mem: 31 016 248) et 3) System.Windows.Markup.BamlDefAttributeKeyStringRecord (éléments: 230 845 mem: 11 080 560). Les octets [] s proviennent de la lecture d'images à partir du disque et de la création de BitmapSources. Les cordes que je ne connais pas, probablement une chose WPF ... – andyhammar

+0

Un autre échantillon: total engagé: 178 Mo, octets privés: 538 Mo. Creuser plus loin ... – andyhammar

1

Vous aimeriez peut-être essayer de lire this article in the latest MSDN magazine. Il va dans le détail sur la façon d'utiliser VADump pour mieux comprendre où la mémoire d'un processus est consacrée.

Vous pouvez télécharger VADump ici: http://go.microsoft.com/fwlink/?LinkId=149683

Décomposer le tas managé, vous pouvez essayer un profileur de mémoire. J'aime personnellement JetBrains dotTrace.

+0

Merci Drew, vadump n'a pas fonctionné pour moi hier mais je l'ai essayé maintenant - rapporte des nombres qui ne correspondent pas eeheap. J'ai posté un commentaire à ma question. – andyhammar

4

J'ai eu un problème similaire dans une application WPF et used UMDH to track où la mémoire native était allouée. (Notez qu'il est généralement utile de set _NT_SYMBOL_PATH pour obtenir de bonnes traces de pile à partir des composants du système d'exploitation.)

Les journaux ont montré que la quasi-totalité de la mémoire était allouée dans le pilote vidéo.J'ai trouvé que le pilote était plus d'un an . de ce jour, j'ai installé la dernière version du site Web du fabricant et que le problème résolu

0

une réponse: Il va à trop de ResourceDictionaries fusionnés (une chose WPF)

Détails: pour pouvoir voir la conception au moment du design dans Blend et VS, nous avons utilisé pour fusionner notre dictionnaire de ressources de thème sur la plupart des pages de xaml Cela a causé une copie de toutes les ressources à être chargé pour chaque contrôle, plus d'informations peuvent être lues ici: [WPF Disciples] [1]

Le seul endroit où je les fusionne maintenant est App.xaml.cs:

<Application.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary 
     Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Résultats: (en cours d'exécution de l'application à travers quelques pages avec un test GUI automatique)

Avant:

  • Après la charge de l'application: 63 Mb
  • Après l'utilisation de l'application : 177 Mb

Après:

  • Une fois le chargement de l'application: 53 Mb
  • Après l'utilisation de l'application: 97 Mb

Je vais poster plus de réponses que je les trouve! (je pensais que ce serait plus facile pour les lecteurs de voir mes conclusions comme des réponses distinctes au lieu de replys aux commentaires - bien?)

[1]: ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1

Questions connexes