2010-06-04 24 views
-1

Je dois créer un programme C# qui traite bien la lecture dans des fichiers volumineux.Lire des lignes à partir d'une boîte de texte/scintilla .NET sans utiliser trop de mémoire?

Par exemple, j'ai un fichier de 60+ mB. J'ai tout lu dans une boîte de scintilla, appelons ça sci_log. Le programme utilise environ 200 Mo de mémoire avec ceci et d'autres caractéristiques. C'est toujours acceptable (et moins que la quantité de mémoire utilisée par Notepad ++ pour ouvrir ce fichier).

J'ai une autre boîte de scintilla, sci_splice. L'utilisateur entre un terme de recherche et le programme recherche dans le fichier (ou sci_log si la longueur du fichier est suffisamment petite - peu importe parce que cela arrive dans les deux sens) pour trouver un regexp.match. Lorsqu'il trouve une correspondance, il concatène cette ligne avec une chaîne qui a des correspondances précédentes et augmente une variable de comptage temporaire. Quand count est 100 (ou 150, ou 200, n'importe quel nombre vraiment), alors je mets la sortie dans sci_splice, appelle GC.Collect(), et répète pour les 100 lignes suivantes (set count = 0, annulant la chaîne).

Je n'ai pas le code sur moi maintenant que j'écris ceci depuis mon ordinateur portable à la maison, mais le problème avec ceci est qu'il utilise beaucoup de mémoire. L'utilisation de mem 200mB saute à plus de 1gB sans fin en vue. Cela n'arrive que sur une recherche avec beaucoup de correspondances regexp, donc c'est quelque chose avec la chaîne. Mais le problème est que le GC ne libérerait-il pas cette mémoire? Aussi, pourquoi monte-t-il si haut? Cela n'a aucun sens de pourquoi cela ferait plus que tripler (pire cas possible). Même si la totalité de ces 200 Mo n'était que la mémoire de connexion, tout ce qu'elle fait est de lire chaque ligne et de la stocker (au pire). Après un peu plus de tests, il semble que quelque chose ne va pas avec Scintilla en utilisant beaucoup de mémoire lors de l'ajout de lignes. La lecture initiale des lignes a un pic de mémoire allant jusqu'à 850mB pendant une fraction de seconde. Je suppose que j'ai juste besoin de paginer la sortie.

+0

S'il vous plaît ne pas inclure les balises dans le titre ("C#"). C'est ce que les tags sont pour. –

+0

Désolé, j'étais sur le point de le réparer. Merci. – Kizaru

+0

60MB n'est pas un énorme fichier. 2Go est un énorme fichier. –

Répondre

0

N'appelez pas GC.Collect. Dans ce cas, je ne pense pas que cela ait de l'importance parce que je pense que cette mémoire va se retrouver sur le gros tas d'objets (LOH). Mais le fait est que .Net en sait beaucoup plus sur la gestion de la mémoire que vous; laisser seul.

Je suppose que vous regardez cela en utilisant le Gestionnaire des tâches juste de la façon dont vous le décrivez. Vous devez utiliser au moins Perfmon. Anticipant vous ne l'avez pas utilisé avant go here and do pretty much what Tess does à l'endroit où il est dit Obtenir un vidage mémoire. Pas sûr que vous êtes prêt pour WinDbg mais que peut-être votre prochaine étape.

Sans voir le code, il n'y a presque aucun moyen de savoir ce qu'il se passe. Le problème pourrait aussi être à l'intérieur de Scintilla, mais je vérifierais ce que vous faites en premier. En exécutant perfmon vous pouvez au moins obtenir plus d'informations pour savoir quoi faire ensuite.

0

Si vous utilisez System.String pour stocker vos lignes correspondantes, je vous suggère de remplacer le fichier par System.Text.StringBuilder et de voir si cela fait une différence.