2009-10-11 6 views
2

J'ai créé DLL en C# 3.5 qui effectue des calculs matriciels intensifs en mémoire où les matrices sont créées et éliminées. Tout fonctionne bien si dll est appelée à partir de l'application .Net mais si elle est appelée à partir de C++, l'utilisation de la mémoire de l'application créée ne fait que grimper jusqu'à ce que la fonction utilisant les matrices soit terminée. Je suppose qu'il y a un problème avec une collecte automatique des ordures.Problème de mémoire en C#, utilisation normale si DLL est appelée par l'application .Net mais astronomique si dll est appelée depuis l'application existante

Répondre

5

Il est très probable que vous ne libérez pas les références aux encapsuleurs d'objets .Net à partir de votre application non gérée. Le GC ne peut pas collecter cette mémoire à moins que toutes les références (y compris les références externes) soient libérées.

+0

Je ne comprends pas, ces nouveaux objets ont été créés en tant que variables locales! Pourquoi sont-ils toujours dans la mémoire après que la fonction soit terminée? Btw, quand j'appelle explicitement .Dispose() sur la plus grande situation de porcs de mémoire obtient beaucoup mieux. –

+0

Les variables locales peuvent contenir des références à des objets non gérés qui ne sont libérés que lorsque Dispose est appelé ou lorsque le GC intervient (en supposant que vous utilisez le modèle Dispose standard). – logicnp

0

Expansion de la réponse de la logique.

Le CLR peut uniquement ramasser la mémoire qui est allouée et possédée par le code managé. Il n'a aucune vue ou compréhension de la mémoire non gérée. Dans le cas de C++ appelant une DLL .Net via COM interop vous avez un mélange de mémoire gérée et non managée. De plus, vous avez des objets C++ qui conservent les objets gérés en vie (via des pointeurs COM et CCW). Le CLR libère les objets gérés correctement, mais uniquement lorsqu'aucune référence n'existe plus. Lorsque C++ accède à un objet géré, il crée un CCW sous le capot qui est maintenu actif par le pointeur d'interface COM C++ natif. Jusqu'à ce que le compte ref sur ce pointeur atteigne 0 via des appels à Release et Add, il maintient le CCW en vie et donc l'objet géré sous-jacent.

Essayez d'envelopper tous les endroits dans C++ où vous accédez à votre objet géré avec un CComPtr et voir si cela prend soin de votre problème.

Questions connexes