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

Framework .NET Discussion :

Stream et GC.Collect()


Sujet :

Framework .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Par défaut Stream et GC.Collect()
    Bonjour à tous,

    j'utilise ce code pour télécharger des fichiers par Socket TCP depuis un server :

    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
     FileInfo Infos = new FileInfo(FilePath);
                    Name = Infos.Name;
                    FileStream FileStream = File.Open(FilePath, FileMode.Open);
                    BinaryReader Reader = new BinaryReader(FileStream);
                    while (FileStream.Position < FileStream.Length)
                    {
                        Byte[] Byte = null;
                        if (FileStream.Length - FileStream.Position >= 262144)
                            Byte = Reader.ReadBytes(262144);
                        else
                            Byte = Reader.ReadBytes((Int32)(FileStream.Length - FileStream.Position));
                        FileS Tr = new FileS(Name, FileStream.Position, FileStream.Length, Byte);
                        this.Enqueue(Packet.Serialize(new Packet(0, Commande, Tr)));
                        Tr = null;
                    }
                    Reader.Close();
                    Reader.Dispose();
                    FileStream.Close();
                    FileStream.Dispose();
                    Reader = null;
                    FileStream = null;
                    GC.Collect();
    Le problème : malgré l'appel à GC.Collect(), quand je sort de la méthode j'ai toujours 1,6 go en mémoire d'utiliser alors que le fichier télécharger faisais 700 mo et qu'avant l'appel à cette méthode, la mémoire utilisée était constante et d'environ 20mo.

    Savez d'où vient le problème ?

    Merci d'avance,
    NeoKript

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    C'est quoi cette ligne ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.Enqueue(Packet.Serialize(new Packet(0, Commande, Tr)));
    Tu stockes les données dans l'objet courant, non ? Donc ça semble normal que ça occupe de la mémoire...

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Par défaut
    Citation Envoyé par tomlev Voir le message
    C'est quoi cette ligne ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.Enqueue(Packet.Serialize(new Packet(0, Commande, Tr)));
    Tu stockes les données dans l'objet courant, non ? Donc ça semble normal que ça occupe de la mémoire...
    Salut,

    Enqueue empile juste des Byte[] afin de les envoyer par socket :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            public void Enqueue(Byte[] Message)
            {
                lock (this)
                {
                    this.Queue.Enqueue(Message);
                }
            }
    Les trame sont dépilées par cette classe :
    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
    this.Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        this.Socket.Connect(new IPEndPoint(Dns.GetHostEntry(IPAddress.Parse("127.0.0.1")).AddressList[0], 10002));
                        List<Socket> Read = new List<Socket>();
                        List<Socket> Write = new List<Socket>();
                        Login L = new Login(Environment.UserName, UserType.Client, String.Empty);
                        this.Worker.Enqueue(Packet.Serialize(new Packet(0, Commande.Login, L)));
                        while (true)
                        {
                            Read.Clear();
                            Write.Clear();
                            Read.Add(this.Socket);
                            if (this.Worker.IsEmpty() == false)
                                Write.Add(this.Socket);
                            Socket.Select(Read, Write, null, 5);
                            if (Read.Count > 0)
                                this.Read();
                            if (Write.Count > 0)
                            {
                                Byte[] Message = this.Worker.Dequeue();
                                this.Socket.Send(Message);
                            }
                        }
    Par contre, ça vient peut-être de la le GC.Collect() n'est peut-être pas fait au bon endroit et toute la mémoire utilisée vient surement de la Queue et du coup le GC.Colect() ne serait pas au bon endroit.

    N'y a t'il pas un moyen de limiter la mémoire utilisée par le processus courante afin que le Garbage Collector passe "plus souvent" ?

    Merci

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Mais le dépilage des trames se fait sur un autre thread, non ? Ou du moins, il n'est pas encore fait quand tu appelles GC.Collect ? Dans ce cas c'est normal qu'il ne collecte pas tout de suite tes trames...

    De toutes façons, la plupart du temps il ne faut pas appeler GC.Collect explicitement. C'est appelé automatiquement quand c'est nécessaire, c'est à dire quand l'OS demande au CLR de lui rendre de la mémoire

    Sinon, ta technique me semble un peu bizarre... à quoi ça sert de charger toutes les trames en mémoire ? Tu peux pas les transmettre au fur et à mesure que tu les lis dans le fichier ? Ca utiliserait beaucoup moins de mémoire

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Par défaut
    En fait, j'ai un Thread qui s'occupe de l'envoie / réception de trame,

    les trames reçu sont empilées dans une queue et dépilée par un autre Thread qui traite les actions à faire dans l'ordre de leurs arrivées et c'est ce thread qui empile les trames à envoyer qui sont traité par le thread s'occupant de l'envoie réception.

    En même temps, j'ai 4go de ram sur le PC actuel, d'où le fait que le GC ne passe que rarement, mais bon.

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

Discussions similaires

  1. DirectSound et le streaming
    Par Shakram dans le forum DirectX
    Réponses: 57
    Dernier message: 09/06/2005, 11h05
  2. [VB6] la collection controls
    Par tomnie dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 30/04/2003, 17h03
  3. Comment enregistrer un stream de longueur fixe ?
    Par Alcarbone dans le forum MFC
    Réponses: 5
    Dernier message: 13/04/2003, 20h14
  4. Comment créér une collection sous Delphi
    Par PsyKroPack dans le forum Langage
    Réponses: 6
    Dernier message: 11/02/2003, 13h20
  5. [VB6] Modifier la clé d'un élément d'une collection
    Par Ricou13 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 21/11/2002, 14h49

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