IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Lecture fichier / Out of memory


Sujet :

C#

  1. #1
    Membre averti
    Inscrit en
    Septembre 2009
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 53
    Par défaut Lecture fichier / Out of memory
    Bonjour je rencontre un problème de Out Of Memory exception

    Le but de mon opération est de lire un fichier qui contient des informations organiser de telle sorte (voir ci dessous) afin de les sauvegarder dans un dictionnaire de dictionnaire :
    AMPS
    1629:852
    1765:1947

    was
    1629:852
    1765:1947
    2156:211
    223:2072
    4302:3892
    4556:1375
    4728:2486
    510:1374
    5846:2723
    6632:1528
    7564:1814

    a
    1629:852
    1765:1947
    2156:211
    223:2072
    4302:3892
    4556:1375
    4728:2486
    510:1374
    5846:2723
    6632:1528
    7564:1814
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
            public void LoadIndexfile(string pathFile)
            {
                StreamReader streamReader = new StreamReader(pathFile, Encoding.UTF8);
                string line = streamReader.ReadLine();
                string saveWord = null;
                string[] lineSplit = null;
     
                Regex myRegex = new Regex(@"^([0-9]+):([0-9]+)$");
                int counter = 0;
     
                while (line != null)
                {
                    counter++;
                    if (line != string.Empty)
                    {
                        if (!myRegex.IsMatch(line))
                        {
                            saveWord = line;
                            listWord.Add(line, new Dictionary<string, int>());
                        }
                        else
                        {
                            lineSplit = line.Split(':');
     
                            if (!listWord[saveWord].ContainsKey(lineSplit[0]))
                                listWord[saveWord].Add(lineSplit[0], Convert.ToInt32(lineSplit[1]));
                        }
                    }
                    if (counter%100000 == 0)
                    {
                        GC.Collect();
                    }
                    line = streamReader.ReadLine();
                }
     
                MessageBox.Show("Génération réussi");
                streamReader.Close();
            }
    Pour moi ce code est relativement simple.
    Rien de très complexe mais j’obtiens cette erreur.
    Mon fichier texte que j'essaye de lire pèse environ 1,5 Go
    J'ai essayer d'apeller le GC comme dans le code mais rien n'y change.

    Je tiens à preciser que l'excption arrive sur differentes ligne, cela depend de l'excceution du programme.

    Voila si vous avez des piste je suis preneur.
    Merci

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 193
    Par défaut
    je sais pas comment est defini listWord mais je pense qu'il ne peut contenir autant d'élément

    ca doit faire un paquet de lignes à lire...

  3. #3
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Appeler le GC ne sert pas à grand chose ici de toute manière.

    D'autant que le problème vient plut probablement de l'accroissment de la taille en mémoire de ListWord (dont on ne sait même pas de quoi il s'agit - Dictionary peut être ?).

    Pourquoi conserver tout cela en mémoire plutôt que faire une injection du fichier dans une base de donnée ?

  4. #4
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Tu expliques que tu veux mettre 1.5Go de données brut en mémoire (donc beaucoup plus en objets). Est ce que tu es sur que le poste sur lequel tu travailles a au moins 8 Go ? (4 serait même trop short je pense)
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  5. #5
    Membre averti
    Inscrit en
    Septembre 2009
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 53
    Par défaut
    oups désolé de ne pas avoir montrer l'objet ListWord, le voila :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dictionary<string, Dictionary<string, int>> listWord;
    De plus peut être que c'est la taille de cette object qui pose mon problème mais j'en doute serieusement.

    En effet dans mon programme j'ai :

    Etape 1: Un corpus de fichier
    Etape 2: Je li tous ces fichiers, et remplie l'objet ListWord (cela fonctionne pas de OOM)
    Etape 3: A partir de cette objet je crée un fichier texte (celui que je vous ai montrer )
    Etape 4: A partir de ce fichier texte je re-crée on objet ListWord qui doit être exactement le même que celui de l'etape 2 (donc qui normalement devrait fonctionner au niveau taille).

    Certe c'est un peu bizarre comme application mais ne me demander pas pourquoi, il s'agit d'un TP que je doit faire en cours : d’où l'impossibilité de travailler avec une base de données (ce n'est pas le but )

    Merci pour vos réponses

    Edit :
    Tu expliques que tu veux mettre 1.5Go de données brut en mémoire (donc beaucoup plus en objets). Est ce que tu es sur que le poste sur lequel tu travailles a au moins 8 Go ? (4 serait même trop short je pense)
    Oui en gros c'est cela. Mon poste n'a que 4 Go...

  6. #6
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Tu expliques que tu veux mettre 1.5Go de données brut en mémoire (donc beaucoup plus en objets).
    D'autant plus que c'est 1.5 Go de texte ASCII mais qu'il met ensuite sous forme de string Unicode en mémoire.

    Bref, je ne comprends pourquoi il déverse pas le tout dans une DB (comme je l'ai mentionné au dessus).

    Car c'est pas le tout de monter les données en mémoire, on peut penser qu'il y a derrière une application pour les utilser, et cette application, il y a de fortes chances pour qu'elle n'ait plus beaucoup de place pour parser les données

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Omsalam Voir le message
    Oui en gros c'est cela. Mon poste n'a que 4 Go...
    Sous quel OS ?

  8. #8
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Omsalam Voir le message
    Etape 1: Un corpus de fichier
    Etape 2: Je li tous ces fichiers, et remplie l'objet ListWord (cela fonctionne pas de OOM)
    Etape 3: A partir de cette objet je crée un fichier texte (celui que je vous ai montrer )
    Sauf que les buffer alloués pour la lecture du fichier final doivent être un chouia plus encombrant que avant.
    C'est peut être à ce moment qu'un appel au GC pourrait être utile, comme le listWord n'a plus d'usage; mais je doute que cela apporte quoi que ce soit.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 193
    Par défaut
    moi je dis

  10. #10
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 193
    Par défaut
    sinon pour être plus constructifs tu fais le test avec un fichier de 50 mega...



    et je pense aussi que tu peux vérifier la taille en cours d'utilisation par ton programme

  11. #11
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Enfin, comme ça a été dit, si tu es sous un Windows (surtout si t'es en 32bits) qui consomme déjà pas mal, que tu mets en mémoire un objet de x Giga (Comme ça a été dit, le wrapper autour de ta donnée brute + l'encodage + le reste) et que par dessus ça tu veux réécrire dans un fichier la même chose dans un fichier y'a pas de magie non plus.

    J'avoue ne pas être assez calé techniquement pour savoir comment fonctionne le stream mais il fait peut être une copie de l'objet à sérialiser avant de le balancer dans le flux. Dans ce cas, ça expliquerait pourquoi ça plante violemment.

    Comme BenoitM l'a dit, tu testes avec des fichiers de 50 Mo (Le TP demande vraiment d'utiliser un fichier d'1.5Go ? w00t ?) et tu vois si ça roule. Enfin, simple rhétorique : Le mec qui a un laptop avec 2Go de RAM, il fait comment ? Il pourra même pas charger le dico complètement que ça plantera xD

    Est ce qu'on pourrait avoir l'énoncé ? Parce que lire un fichier, le foutre dans un dico et le réécrire sous une autre forme, ça peut avoir du sens comme algo, ça fait manipuler des streams et tout, mais le faire avec un fichier de 1.5Go je vois juste pas l'intérêt ...
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  12. #12
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Enfin, comme ça a été dit, si tu es sous un Windows (surtout si t'es en 32bits) ...
    En Xp 32 bits son espace d'adressage par process est de toute manière limité à 2Go.

  13. #13
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Justement, ça serait encore pire
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  14. #14
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Justement, ça serait encore pire
    Oui, c'est juste pour dire, que même si il a 4 Go, il ne peut adresser que 2 si son programme est en 32 bits (bon la limitation est contournable en positionnant l'indicateur IMAGE_FILE_LARGE_ADDRESS_AWARE , mais je ne sais pas si c'est applicable avec les applications .Net, ni comment faire dans ce cas).

    Avec ce flag (qui indique juste au système que l'adresse mémoire sera reconnue comme un entier positif par le système) on peut grimper l'adressage d'un process 32 bits à environ 3 Go sur un OS 32, et avoir un plein adressage de 4 Go sur un système 64 bits(toujours dans le cas d'un process 32 bits).

    EDIT : La question m'a intriguée et, après recherche sur le net, c'est faisable avec les applis .NET en utilisant la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    editbin /LARGEADDRESSAWARE

  15. #15
    Membre émérite

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Par défaut
    Il en faut peu pour t'intriguer ! Qu'en est il de la réponse à la grande réponse de la vie, de l'univers et de tout le reste, tu planches encore dessus ?

    (Désolé pour le HS)
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  16. #16
    Membre averti
    Inscrit en
    Septembre 2009
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 53
    Par défaut
    Bonsoir et merci pour vos réponse.

    J'ai pu résoudre mon problème en diminuant la taille du fichier car en faite je stockai beaucoup trop de donnée en double ce qui ma permet de bien le réduire.

    En tout cas j'ai appris des choses sur le stockage et le fonctionnement de windows 32 bit qui est bien mon cas justement et je met de cotés ces informations surtout au niveau du IMAGE_FILE_LARGE_ADDRESS_AWARE

    Est ce qu'on pourrait avoir l'énoncé ? Parce que lire un fichier, le foutre dans un dico et le réécrire sous une autre forme, ça peut avoir du sens comme algo, ça fait manipuler des streams et tout, mais le faire avec un fichier de 1.5Go je vois juste pas l'intérêt ...
    En faite oui le TP a du sens ^^ j'aurais peut être du le préciser.
    Le but est qu'on possède un corpus de petit fichier texte (5000 qui correspond à un dump de wikipedia).

    Le but est de lire ces 5000 fichiers et de stocker, crée mon listWord un index inversé :
    term1
    - apparait document1 : 15 fois
    - apparait document2 : 10 fois
    - apparait document456 : 25 fois

    Avec cette index inversé, il fallait pouvoir aussi l’écrire dans un fichier mais aussi lire ce fichier et recrée "ListWord" (cela nous evite donc de reparser le contenu du corpus de fichier)

    Voila voila
    Encore merçi à vous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Gros fichier mysql : out of memory
    Par xavier_dcf dans le forum Administration et Installation
    Réponses: 6
    Dernier message: 21/02/2013, 15h26
  2. très gros fichier et out of memory
    Par Narrow dans le forum Langage
    Réponses: 7
    Dernier message: 01/09/2010, 16h30
  3. Pb de 'out of memory' lors de traitements de fichiers
    Par DelphLaga dans le forum Langage
    Réponses: 1
    Dernier message: 21/03/2008, 21h12
  4. Réponses: 4
    Dernier message: 23/05/2007, 22h29
  5. [langage] prob lecture fichier .txt
    Par martijan dans le forum Langage
    Réponses: 3
    Dernier message: 16/07/2003, 11h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo