8
votes

Fuite de la mémoire Lorsque vous appelez le code non géré du code géré dans Windows 7

Lorsque j'appelle un code C ++ non géré de mon code C #, je semble avoir une sorte de fuite de mémoire.
Le C ++ lit les données d'un fichier en utilisant ifstream.read, et l'écrit à un vecteur.

Cela ne se produit qu'après la mise à niveau vers Windows 7, ne se produit pas sur Vista, mais si j'utilise une version de la DLL natif qui était compilé sur Vista, ça ne change rien!
Si j'exécute le même code C ++ directement, sans interope géré, il n'y a pas de fuite de mémoire!
Si j'exécute le processus géré, mais dans le processus de Vshost, il n'y a pas de fuite de mémoire!

Voici la signature d'appel: xxx

et le natif : xxx

Lorsque je l'appelle de C ++, j'appelle-la comme ceci: xxx

Quand je regarde la performance Compteurs pour la mémoire gérée et non gérée, je vois que toute la mémoire provient du code non géré.
Considérant que le maréchaling est assez simple, je ne comprends pas pourquoi il y a une différence entre appeler le C ++ directement ou par C #.
Je ne sais pas non plus pourquoi cela ne se produirait-il que sur Windows 7 (les deux installations de Windows avaient .NET 3.5 SP1).

Est-ce que quelqu'un a une idée quelle est la raison de cela?

Également si quelqu'un connaît un outil de profilage de mémoire native qui fonctionne sur la fenêtre 7, je serais heureux de savoir (pour l'instant je viens d'imprimer pour consoler toute allocation de mémoire explicite et qu'il n'y a pas de différence).


4 commentaires

Leakdiag [ McFunley.com/277/... ou AQTime AQTime d'automateqa peut faire une analyse des fuites non gérées.


Quel compteur de performance utilisez-vous pour mesurer la consommation de mémoire?


Vous avez étiqueté la question "vshost.exe". L'application est-elle exécutée sous Visual Studio lorsque vous mesurez la consommation de mémoire?


@LOU: Ni travaille sur Windows 7. @Peter: j'ai vérifié "processus - octets privés" pour des allocations autochtones et la mémoire CLR pour gérée. J'ai marqué Vshost.exe parce que "si j'exécute le processus géré, mais dans le processus de Vshost, il n'y a pas de fuite de mémoire", les mesures de mémoire ont diminué sur le processus normal.


4 Réponses :


2
votes

Malheureusement, une fois que vous impliquez des cordes, aucun marshalling n'est simple.

Nous allons avoir besoin de plus de données afin de vous aider à suivre ce problème. Pouvez-vous fournir le suivant

  • Méthode native Signature
  • Comment la mémoire est-elle réalisée dans le code natif?
  • Peut-être l'échantillon C ++ où vous utilisez l'API?

    edit

    Essayez la signature suivante. Cela indique au CLR de ne pas savoir la mémoire maréchal dans les deux sens mais ne transmettez que les données de. xxx


1 commentaires

Le [IN] n'a pas aidé, pourquoi changerait-il entre Vista et Windows 7? En outre, je n'ai pas mentionné que j'appelle cette méthode une seule fois.



1
votes

J'ai trouvé l'utilisation de la Profiler CLR utile lorsque vous trouvez ma fuite de mémoire.


0 commentaires

0
votes

Êtes-vous sûr qu'il y a une fuite de mémoire?

Quelle est votre base pour déterminer la fuite de mémoire. Vous dites que vous pouvez le voir des compteurs de performance, mais que observez-vous réellement? Voyez-vous une courbe de montée continue, ou celle qui s'installe à un niveau élevé? Une consommation de mémoire élevée est souvent confondue pour une fuite de mémoire.

BTW. Pouvez-vous poster votre définition de fonction C ++ aussi?


1 commentaires

Je vois une courbe en continu. J'ai posté la définition de la fonction C ++, si vous voulez dire le corps, il suffit de lire des données à partir d'un fichier en utilisant ifstream.read.



5
votes

Je suis sûr que le problème est associé à la mise en place des types de données C # à leurs pièces de comptoir C ++. Puisque vous préparez la valeur de retour Bool sur une valeur d'octets signée, vous devriez peut-être faire la même chose aux arguments de la fonction? Le type C # Bool est de 4 octets, peut-être que vous fuyez là-bas?

En outre, la spécification du type non géré pour les chaînes peut aider. xxx

une explication du commentateur:

Pour le type C ++ BOOL:

en général, un point zéro ou null-pointeur la valeur est convertie en faux, tout autre la valeur est convertie en true.

...

La bibliothèque standard C ++ de 1998 définit une spécialisation du vecteur modèle pour Bool. La description de La classe indique que le La mise en œuvre devrait emballer le éléments de sorte que chaque bool utilise seulement un peu de mémoire.

Donc, à peu près toute valeur que vous utilisez, vous obtiendrez une boolean C ++ avec la valeur true ou false.


6 commentaires

Si la taille de Bool est incompatible avec la taille, il ne serait pas une fuite de mémoire, mais probablement une violation d'accès, ou une sorte de corruption de pile.


Nice File Scott, C # Les maréchaux Bools comme 4bytes. L'attribut Marshalas était porté disparu pour V et W. blogs.msdn.com/oldnewthing/archive/2009/08/ 13/9867383.aspx


Merci, c'est une belle lecture mais ça n'a pas aidé. Comme je l'ai mentionné dans un autre commentaire, j'appelle cette méthode une seule fois, alors même s'il y avait une fuite là-bas, cela ne serait pas perceptible.


@Meidan Alon, combien de mémoire allez-vous fuir lorsque vous appelez la méthode?


J'ai mesurer à 2 points à temps. Sans les bytes privés de fuite sont à 37k et 66k; Avec la fuite, il est à 90k et 1,7 g. Donc, il grandit vraiment vite!


À ce stade, je pense que vous allez devoir ajouter plus d'informations sur le code géré. Je devine la raison pour laquelle votre code non géré ne fuit pas est que la fuite n'est pas dans cette fonction.