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 :

Question sur la libération de mémoire


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Par défaut Question sur la libération de mémoire
    Bonjour,

    Je me pose des questions sur la libération correcte de la mémoire. (VS 2008, ici sur une appli WCF)


    Sur cet exemple, comment faire pour être sûr que la mémoire est totalement libérée ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    using System.IO;
    [...]
      /// <summary>
      /// Renvoie la date de dernière modification du fichier
      /// </summary>
      public DateTime LastModif
      {
        get
        {
            return new FileInfo(FilePathName).LastWriteTime;
        }
      }
    [...]
    Est-ce que ce code serait mieux ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      public DateTime LastModif
      {
        get
        {
          FileInfo fi = new FileInfo(FilePathName);
          try
          {
            return fi.LastWriteTime;
          }
          finally
          {
            fi = null;
          }
        }

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2005
    Messages : 700
    Par défaut
    Citation Envoyé par adaneels Voir le message
    Sur cet exemple, comment faire pour être sûr que la mémoire est totalement libérée ?
    En faisant confiance au Garbage collector :-)
    Sachant que DateTime est en + un type valeur, tu ne conserveras aucune référence à FileInfo par la suite => GC 0 direct.

    Il faut faire attention à tout objet héritant de IDisposable, et éviter certaines boucles qui bourrinent dans le GC inutilement. Pour la libération mémoire des IDisposable, il est convenu d'utiliser le
    using(IDisposable){ ... }


    Le Try finally est ici + qu'inutile, ce qui importe par contre dans cet exemple ce sont les possibles exceptions du à un mauvais Path :
    Exceptions:
    System.ArgumentNullException: fileName is null.
    System.Security.SecurityException: The caller does not have the required permission.
    System.ArgumentException: The file name is empty, contains only white spaces, or contains invalid characters.
    System.UnauthorizedAccessException: Access to fileName is denied.
    System.IO.PathTooLongException: The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.
    System.NotSupportedException: fileName contains a colon ( in the middle of the string.
    Si ton Path est un membre privé, il serait préférable de directement conservé une référence à FileInfo, ou alors de le créer au Set de FilePathName. Enfin, tout est question de choix.

    Cela dit, si une exception pète, il y a un problème : il faut le traiter d'une façon ou d'une autre...

  3. #3
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Yep, comme le dit Chubyone, FileInfo n'implémente pas IDisposable : c'est donc qu'il ne détient aucune ressource non managée, et que donc qu'il n'y à rien à faire.

    La mémoire est une ressource managée, donc on y touche pas (plus précisement, on peut pas ), et on laisse le GC nettoyer les objets morts quand il en a envie.

  4. #4
    Membre éclairé
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Par défaut
    OK.
    Je me posais la question parce qu'il y avait un new et venant de Delphi, j'ai l'habitude de penser "Tout Create doit avoir son Free.".

    Pour les using et dispose, oui oui, je fais gaffe

    Lorsque je regarde tout ce qu'il se dit sur Internet sur "comment éviter les fuites de mémoire" ou "comment bien libérer la mémoire utilisée", je vois beaucoup "mettez vos variables à null" !

    Hors, à moins d'avoir un type nullable, il n'y a que les string, object et les collections que l'on peut mettre à null (à ma connaissance mais je n'ai pas testé tous les types ).
    Mais ça me paraît bizarre de mettre à null tous mes strings avant de sortir d'une fonction...
    Ces objets sont pourtant bien managés et ils sont bien libérés (en supposant qu'il n'y ait que des variables locales) au prochain passage du GC après que la fonction ait été exécutée, non ?

    Arnaud DANEELS
    un développeur qui se pose des questions sur la gestion de mémoire en C# alors que c'était plus simple en Delphi ou en C : on alloue et on désalloue soi-même.

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2005
    Messages : 700
    Par défaut
    Il y a deux "types" en .Net : les types valeurs, int, float, DateTime, ou Struct plus généralement, et les types références : tout le reste.

    Renseignes toi sur la MSDN il y a pas mal d'explications la dessus

    Puisque tu en parles il y a une précision importante a BIEN retenir : le type string est IMMUTABLE : toute modification entraine une nouvelle instance. De cette connaissance, à toi de savoir quoi faire, et surtout NE PAS faire
    La dessus aussi la MSDN a de quoi t'offrir pleins d'explications

  7. #7
    Membre éclairé
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Par défaut
    Merci pour le lien .

    Ca me rassure

  8. #8
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par adaneels Voir le message
    Lorsque je regarde tout ce qu'il se dit sur Internet sur "comment éviter les fuites de mémoire" ou "comment bien libérer la mémoire utilisée", je vois beaucoup "mettez vos variables à null" !
    Ce qui ne sert à rien, à par pourrir le code de lignes inutiles
    Mettre à null, ce n'est que couper le lien entre une référence et l'objet qu'elle référençait. Ca ne libère pas l'objet.
    Pourquoi ne peut on pas libérer la mémoire à la main ? Ben c'est simple : un objet peut être référencé par un paquet d'objets vivants. Si on pouvait le libérer (via un "delete uneDesRéférences"), ça voudrait dire que toutes ces références seraient invalides. Et en C#, t'as l'assurance que toute référence est valide.

    Donc, répète après moi, comme un mantra : j'oublie tout ce que je sais de la gestion de la mémoire en C ou Delphi, et je ne m'occupe que des autres ressources (connexion réseau, handle, etc.) en C# avec le pattern IDisposable

  9. #9
    Membre éclairé
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Donc, répète après moi, comme un mantra : j'oublie tout ce que je sais de la gestion de la mémoire en C ou Delphi, et je ne m'occupe que des autres ressources (connexion réseau, handle, etc.) en C# avec le pattern IDisposable
    OK OK lol
    je suis repasser dans les lignes que j'ai modifié hier pour enlever ces nulls . J'avais fait ça pour voir si ça améliorer quelquechose mais ça me plaît bien mieux sans ces null partout


    Deux autres questions :
    - les collections : je suppose que l'on n'a pas besoin de les vider sauf si le type de données dérive de IDisposable. j'ai juste ?
    - Si j'ai bien compris la politique en C# : ce type-ci n'a pas besoin d'avoir son Dispose :
    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
    39
    40
    41
    42
    43
    44
    45
    46
    public class TOCLogItem : INotifyPropertyChanged
    {
      private DateTime _Dt;
      private TOCLogGravity _Gravity;
      private string _Message;
     
      public DateTime Dt
      {
        get { return _Dt; }
        set
        {
          _Dt = value;
          if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Dt"));
        }
      }
      public TOCLogGravity Gravity
      {
        get { return _Gravity; }
        set
        {
          _Gravity = value;
          if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Gravity"));
        }
      }
      public string Message
      {
        get { return _Message; }
        set
        {
          _Message = value;
          if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Message"));
        }
      }
     
      public TOCLogItem(DateTime dt, TOCLogGravity gravity, string message)
      {
        this.Dt = dt;
        this.Gravity = gravity;
        this.Message = message;
      }
     
      public event PropertyChangedEventHandler PropertyChanged;
    }
    j'ai juste ?

  10. #10
    Membre éclairé
    Avatar de adaneels
    Homme Profil pro
    Chef de projet MOA
    Inscrit en
    Août 2006
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA

    Informations forums :
    Inscription : Août 2006
    Messages : 236
    Par défaut
    Citation Envoyé par Chubyone Voir le message
    Le Try finally est ici + qu'inutile
    Ca me rassure grandement de ne pas avoir à pourrir mon code

    Citation Envoyé par Chubyone Voir le message
    Si ton Path est un membre privé, il serait préférable de directement conservé une référence à FileInfo, ou alors de le créer au Set de FilePathName. Enfin, tout est question de choix.
    Bien deviné, c'est une propriété privée.
    Dans le cas présent, le Path est utilisé pour d'autres choses et ne sert dans un FileInfo que pour cette méthode.
    Merci pour le conseil tout de même, tout conseil est le bienvenue.

Discussions similaires

  1. questions sur la libération d'ingrid de bétancourt
    Par shadowmoon dans le forum Politique
    Réponses: 5
    Dernier message: 03/09/2008, 20h08
  2. Question sur l'allocation de mémoire
    Par Fonzy007 dans le forum Linux
    Réponses: 8
    Dernier message: 26/12/2006, 09h29
  3. Quelques questions sur la mémoire
    Par Gruik dans le forum C
    Réponses: 6
    Dernier message: 17/11/2004, 14h38
  4. Question simple sur la libération des objets
    Par gibet_b dans le forum Langage
    Réponses: 2
    Dernier message: 12/07/2004, 10h01
  5. Réponses: 25
    Dernier message: 16/07/2003, 20h41

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