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 :

[C#] Pourquoi ai-je une consommation de mémoire importante ?


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2006
    Messages : 30
    Par défaut [C#] Pourquoi ai-je une consommation de mémoire importante ?
    Bonjour à tous,

    J'ai rencontré à la job une situation étrange que je ne sais pas expliquée: j'ai une séquence dans le programme qui consomme énormément de mémoire. Voici le code incriminé:

    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
     
    class Program
    {
            static void Main(string[] args)
            {
                const int NB_ELEMENTS = 100000;
     
                Vector Y = new Vector(NB_ELEMENTS,1.0);
     
                int i = 1;
                double h = 2.0;
     
                Vector u = new Vector();
     
                do
                {
                    u = (0.5 - Y) / h;
     
                    i++;
     
                } while (i <= NB_ELEMENTS);
     
                return;
            }
    }
    Le problème se situe à la ligne suivante:

    où Y et u sont des objets Vecteur. À chaque passage sur cette ligne, le programme consomme 2M de mémoire et elle apparait comme «perdue».

    Voici aussi le constructeur de la classe ainsi que l'implémentation de l'opérateur de soustraction.

    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
     
    public Vector(int nrows, int ncols)
    {
            _nbelems = nrows*ncols;
            _nrows = nrows;
            _ncols = ncols; 
            _pElements = new double[nrows,ncols];
    }
     
    public static Vector operator-(double lhs, Vector rhs)
    {
           Vector Res = new Vector(rhs.nrows, rhs.ncols);
           for (int i = 1; i <= rhs.nbelems; i++)
           {
                  Res[i] = lhs - rhs[i];
            }
     
            return Res;
    }
    Ci-joint une capture d'écran de la mémoire vive.

    Auriez-vous une idée de ce que j'ai fait de mauvais?

    Merci!

    Christophe.
    Images attachées Images attachées  

  2. #2
    Rédacteur
    Avatar de cladsam
    Profil pro
    Inscrit en
    Août 2003
    Messages
    1 787
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Août 2003
    Messages : 1 787
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      do
                {
                    double KSum = double.NaN;
     
                    u = (0.5 - Y) / h;
     
                } while (i <= NB_ELEMENTS);
    Si tu n'incremente jamais I... sur que ta boucle va durer ^^
    En plus , a quoi bon redéclarer KSUm a chaque tour de boucle?

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2006
    Messages : 30
    Par défaut
    L'incrément était un oubli de ma part; je n'ai pas mis le code complet car il n'est pas en cause. Seule l'opération sur les Vecteurs est problèmatique.

  4. #4
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Par défaut
    Salut .

    La gestion de la mémoire est particuliere sous dotnet.

    je te conseil cette Q/R et la recherche sur le forum, le sujet à été mainte fois traité.

  5. #5
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Question bête: c'est quoi cette classe Vector que tu utilises ? Je n'ai pastrouvé de classe identique dans la MSDN.... ?

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Juillet 2006
    Messages : 30
    Par défaut
    Citation Envoyé par dev01
    Salut .

    La gestion de la mémoire est particuliere sous dotnet.

    je te conseil cette Q/R et la recherche sur le forum, le sujet à été mainte fois traité.
    Ce qui me semble étrange, c'est que si je remplace la classe Vecteur (que nous avons développé et qui ne fait qu'encapsuler un tableau de double[,] et utilise un index de base à 1) par un tableau de double [], tout fonctionne à merveille.

    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
    Vector X = new Vector(500,0.0);
    Vector Y = new Vector(100000,0.0);
    double KSum = 0.0;
    do 
    {	
                    //u = (X[i]- Y)/ h;
                    double[] u = new double[Y.nbelems];
     
                    for (int j = 0; j < u.Length; j++)
                    {
                        u[j] = (X[i] - Y[j+1]) / h;
                    }
     
     
    	   //Computes the standard Normal (scalar) probability density function. 
    	   //KK = Normal.pdfStdNormal( u );
                    Normal.pdfStdNormal( u.Length, u, ref u);
     
                    //KSum = KK.sum();
                    foreach (double Valeur in u)
                    {
                        KSum += Valeur;
                    }
     
    	    i++;
     
                     KSum = 0.0;
    } while (i <= 500);

  7. #7
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    C'est normal que ce soit gourmand en mémoire.
    Analyse de près ton 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
    39
    40
    41
     
    class Program
    {
            static void Main(string[] args)
            {
                const int NB_ELEMENTS = 100000;
     
                Vector Y = new Vector(NB_ELEMENTS,1.0); // Création d'un
     vecteur de 100000 elements
     
                int i = 1;
                double h = 2.0;
     
                Vector u = new Vector(); // Création d'un vecteur vide je
     suppose (pas de constructeur posté)
     
                do
                {
                    u = (0.5 - Y) / h; // Ici à chaque fois, tu recrée en mémoire
     un nouveau vecteur de 100000 elements (le vecteur Res dans le code de
     l'opérateur.). Et celui que u contient avant l'affectation est perdu. Cette
     opération est faite 100000 fois dans ta boucle.
     
                    i++;
     
                } while (i <= NB_ELEMENTS);
     
                return;
            }
    }
     
    public static Vector operator-(double lhs, Vector rhs)
    {
           Vector Res = new Vector(rhs.nrows, rhs.ncols);
           for (int i = 1; i <= rhs.nbelems; i++)
           {
                  Res[i] = lhs - rhs[i];
            }
     
            return Res;
    }
    Avec un tableau de double je pense que ça va plus vite car c'est un tableau de type valeurs alors que les variable Vector sont des références. C'est une des explications.

  8. #8
    Membre Expert Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Par défaut
    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
    class Program
    {
            static void Main(string[] args)
            {
                const int NB_ELEMENTS = 100000;
     
                Vector Y = new Vector(NB_ELEMENTS,1.0);
     
                int i = 1;
                double h = 2.0;
     
                Vector u = new Vector();  // sert à quoi ?
     
                do
                {
                    u = (0.5 - Y) / h;   // on instancie plein de vecteurs sûrement
     pour rien.
     
                    i++;
     
                } while (i <= NB_ELEMENTS);
     
                return;
            }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public static Vector operator-(double lhs, Vector rhs)
    {
           Vector Res = new Vector(rhs.nrows, rhs.ncols);
           for (int i = 1; i <= rhs.nbelems; i++)
           {
                  Res[i] = lhs - rhs[i];
            }
     
            return Res;
    }
    Faudrait peut-être changer ça.

    Au lieu d'instancier un nouveau vecteur à chaque cycle de la boucle, faudrait peut-être faire ce que tu avais, apparemment, initialement l'intention de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Vector u = new Vector();
     
    do
    {
        Vector.compute(0.5,Y,h,u);
     
        i++;
     
    } while (i <= NB_ELEMENTS);
    avec Vector.compute(in double, in Vector, in double, out u) une méthode statique de Vector de ce genre là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public static void compute(double lhs, Vector rhs, double h, out Vector u){
        if(u.nbelems != rhs.nbelems)
            throw new ArgumentException("blabla vecteur u pas cool...");
        for (int i = 1; i <= rhs.nbelems; i++)
        {
            u[i] = (lhs - rhs[i]) / h; // ou quelque soit l'opération de division...
        }
    }

Discussions similaires

  1. [ADO.Net][C#] Pourquoi OracleConnection lève une exception ?
    Par meuledor dans le forum Accès aux données
    Réponses: 2
    Dernier message: 26/01/2006, 18h54
  2. Réponses: 2
    Dernier message: 26/10/2005, 12h44
  3. Réponses: 12
    Dernier message: 14/07/2005, 17h55
  4. Réponses: 9
    Dernier message: 31/05/2005, 11h05

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