J'ai écrit un programme qui analyse le code source d'un projet et rapporte divers problèmes et métriques basés sur le code. P>
Pour analyser le code source, je charge les fichiers de code existants dans la structure du répertoire du projet et analysez le code de la mémoire. Le code passe par un traitement étendu avant qu'il soit passé à d'autres méthodes à analyser davantage. P>
Le code est transmis à plusieurs classes lorsqu'il est traité. p>
L'autre jour, je l'exécutais sur l'un des projets plus vastes que mon groupe a, et mon programme s'est crevé sur moi car il y avait trop de code source chargé dans la mémoire. C'est un cas d'angle à ce stade, mais je veux pouvoir gérer cette question à l'avenir. p>
Quel serait le meilleur moyen d'éviter les problèmes de mémoire? P>
Je pense au chargement du code, faites le traitement initial du fichier, puis sérialisez les résultats sur le disque, de sorte que lorsque je dois y accéder à nouveau, je n'ai pas besoin de passer à travers le processus de manipulation de la brute code à nouveau. Est-ce que ça a du sens? Ou la sérialisation / la désérialisation est-elle plus chère, puis le traitement du code à nouveau? P>
Je veux garder un niveau de performance raisonnable tout en répondant à ce problème. La plupart du temps, le code source s'intégrera à la mémoire sans problème. Il y a donc un moyen de «page» que de mes informations lorsque je suis faible en mémoire? Y a-t-il un moyen de dire quand mon application est en cours d'exécution sur la mémoire? P>
4 Réponses :
Utilisez WINDBG avec SOS pour voir ce qui se tient sur les références de chaîne (ou ce qui est tout ce qui cause l'utilisation extrême de la mémoire). P>
Cela concerne le fait que le dossier que j'analysais était de 1,6 Go (y compris les fichiers binaires compilés, mais je ne charge pas ceux-ci, la quantité de code est toujours massive)
Serializing / désérialisant des sons comme une bonne stratégie. J'ai fait une belle quantité de cela et c'est très rapide. En fait, j'ai une application qui instanciait des objets à partir d'un DB, puis les sérialise aux disques durs de mes nœuds Web. Cela a été un moment depuis que je l'ai comparé, mais elle était sérialisée plusieurs centaines d'une seconde et peut-être plus de 1 000 de retour lorsque je faisais des tests de charge. P>
Bien sûr, cela dépendra de la taille de vos fichiers de code. Mes fichiers étaient assez petits. P>
Si le problème est qu'une copie unique de votre code vous oblige à remplir la mémoire disponible, il y a au moins deux options. P>
Vous devez également vérifier si vous éliminez correctement les objets. Avez-vous des problèmes de mémoire en raison d'anciennes copies d'objets en mémoire? P>
1,6 Go est toujours gérable et ne doit pas causer de problèmes de mémoire. Les opérations de cordes inefficaces pourraient le faire. p>
Comme vous analysez le code source, vous vous séparez probablement de certaines sous-chaînes - jetons ou quoi vous les appelez. Si vos jetons ont combiné le compte de code source entier, cela double la consommation de mémoire juste là-bas. En fonction de la complexité du traitement, vous faites le puplier peut être encore plus grand. Mon premier geste ici serait de regarder de plus près sur la manière dont vous utilisez vos chaînes et de trouver un moyen d'optimiser - c'est-à-dire jeter l'origion après la première passe, comprimer les succursales ou utiliser des index (pointeurs) sur les cordes d'origine plutôt que Substrings réels - Un certain nombre de techniques peuvent être utiles ici. P>
Si rien de tout cela ne pourrait aider que je serais recourir à les échanger contre le disque p>
Cela a du sens, car j'ai divers états du dossier disponibles, augmentant probablement la taille trois fois
J'irais avec l'approche de sérialisation. Mais regardez le code source de Findbug. Ils font quelque chose de similaire et ils ont peut-être déjà résolu ce problème: FindBugs.sourceforge.net/downloads.html a>
Quel est le rapport entre la taille en mémoire et la taille des fichiers sur disque?
Vous avez mentionné des cordes de passage entre les cours. Selon la façon dont vous gérez des chaînes, des copies sont peut-être faites et vous utilisez donc plus de mémoire que vous ne devez. Je ne sais pas exactement comment C # gère les cordes de passage, mais si elle les reproduit, cela peut être le problème.