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 :

OutOfMemory avec datagridview incompréhensible


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut OutOfMemory avec datagridview incompréhensible
    Bonjour à tous, je rencontre un problème avec un datagridview que je n'arrive pas à résoudre seul. J'appelle donc à votre gentillesse et vos connaissance pour m'aider.

    J'ai une list d'object qui comprend +/- 630.000 object.

    j'affiche cette liste dans un datagridview de la manière suivante :

    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
    47
    48
    49
    50
    51
    52
    53
    public void SetMarks(List<Mark> lst)
    		{
    			if (lst.Count == 0 || lst == null) return;
     
    			dtgv.CellFormatting += dtgv_CellFormatting;
     
    			if (dtgv.Rows.Count != 0)
    			{
    				dtgv.DataSource = null;
    				dtgv.Rows.Clear();
    			}
     
    			dtgv.AutoGenerateColumns = false;
    			dtgv.Columns[3].DataPropertyName = "Titre";
    			dtgv.Columns[4].DataPropertyName = "Link";	
    			dtgv.Columns[7].DataPropertyName = "Description";
    			dtgv.Columns[8].DataPropertyName = "KeyWords";
     
    			dtgv.DataSource = lst;
     
    			OnDataChanged();
    		}
     
    		void dtgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    		{
    			int colIndex = e.ColumnIndex;
    			int rowIndex = e.RowIndex;
     
    			Mark mk = dtgv.Rows[rowIndex].DataBoundItem as Mark;
     
    			switch (colIndex)
    			{
    				case 1:
    					dtgv.Rows[rowIndex].Cells[1].Style.BackColor = mk.CheckInfo.Couleur;
    					break;
    				case 2:
    					dtgv.Rows[rowIndex].Cells[2].Value = mk.CheckInfo.CodeRetour;
    					break;
    				case 4:
    					if(Helpers.UrlHlp.IsFromDarkWeb(mk.Link)) dtgv.Rows[rowIndex].Cells[4].Style.ForeColor = Color.Red;
    					break;
    				case 5:
    					if(Helpers.FileHlp.UrlIsFile(mk.Link) == true)
    					{
    						dtgv.Rows[rowIndex].Cells[5].Value = " ";
    						dtgv.Rows[rowIndex].Cells[5].Style.BackColor =	Color.Black;
    					}
    					break;
    				case 6:
    					dtgv.Rows[rowIndex].Cells[6].Value = mk.CheckInfo.RedirectionURL;
    					break;
    			}	
    		}
    jusque là je n'ai pas de problème l'affichage du datagridview ce passe bien.

    Souhaitant supprimer tous les doublons de manière visible, je sélectionne toute les ligne (via un bouton) sauf une avec la procédure suivante:

    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
    	private void BtSelectAllClick(object sender, EventArgs e)
    		{
    			if(dtgv.Rows.Count == 0) return;
     
    			string baseCompare = dtgv.Rows[0].Cells[dtgv.COLLINK].Value.ToString();
     
    			dtgv.SuspendLayout();
    			for(int i = 1; i < dtgv.Rows.Count ; i++)
    			{
    				if(dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString() == baseCompare)
    					dtgv.Rows[i].Selected = true;
    				else
    					baseCompare = dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString();
    			}
    			dtgv.ResumeLayout();
     
    			dtgv.Focus();
    		}
    et là j'obtiens de manière aléatoire l'erreur suivante :

    à System.Windows.Forms.DataGridViewTextBoxCell.Clone()
    à System.Windows.Forms.DataGridViewRow.CloneCells(DataGridViewRow rowTemplate)
    à System.Windows.Forms.DataGridViewRow.Clone()
    à System.Windows.Forms.DataGridViewRowCollection.get_Item(Int32 index)
    à NoDouble.Gui.Double.SelectAllButOne() dans i:\Perso C#\Webmark-IDEA\WebMark\WebMark\WebMark\Gui\Double.cs:ligne 109
    à NoDouble.Gui.Double.BtSelectAllClick(Object sender, EventArgs e) dans i:\Perso C#\Webmark-IDEA\WebMark\WebMark\WebMark\Gui\Double.cs:ligne 94
    à System.Windows.Forms.Control.OnClick(EventArgs e)
    à System.Windows.Forms.Button.OnClick(EventArgs e)
    à System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    à System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    à System.Windows.Forms.Control.WndProc(Message& m)
    à System.Windows.Forms.ButtonBase.WndProc(Message& m)
    à System.Windows.Forms.Button.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    la ligne 109 de double.cs est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    				if(dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString() == baseCompare)
    					dtgv.Rows[i].Selected = true;
    				else
    					baseCompare = dtgv.Rows[i].Cells[dtgv.COLLINK].Value.ToString();
    La question est donc comment empêcher l'erreur OutOfMemory et comment se fait-il qu'elle se produise puisque l'affichage du datagridview se fait correctement ???

    En tous cas, merci pour votre aide et éclaircissement à venir.

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 897
    Points : 1 913
    Points
    1 913
    Par défaut
    Tu as donné la stacktrace mais pas l'exception qui est levée.

  3. #3
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    l'exception est System.OutOfMemory

    Ce qui m'étonne c'est que l'erreur survient de manière aléatoire et sans modifier cette partie de code

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    outofmemory par définition peut arriver n'importe où
    la pile des appels ne sert alors pas à grand chose, car ca peut tomber chez toi comme dans le framework
    elle ne montre que la goutte d'eau qui a fait débordé le vase, pas qui a remplit le vase comme un sagouin sans appeler de Dispose


    par contre ca dit que tu fais un truc qui alloue énormément de mémoire (des centaines de Mo) en très peu de temps
    le garbage collector n'a pas le temps de gérer tout ce qui n'est plus utilisé
    tu peux vérifier dans le gestionnaire de tâches d'ailleurs pour confirmer

    par contre le code que tu nous montre je ne vois rien qui saute aux yeux, tu créés des images ou d'autres trucs volumineux et non managés quelque part ? (ça peut être totalement ailleurs)
    (un logiciel de profiling mémoire .net pourrait te dire quel type d'objet consomme beaucoup de mémoire, et t'aiguiller sur la recherche du code associé, mais c'est pas toujours simple à utiliser)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    La question est donc comment empêcher l'erreur OutOfMemory et comment se fait-il qu'elle se produise puisque l'affichage du datagridview se fait correctement ???
    Ce n'est pas parce que l'affichage se fait sans heurt que tu as suffisamment de mémoire pour gérer toutes les actions. D'ailleurs, il suffit de voir la trace que tu nous as fournis. Avec des méthodes Clone, on peut supposer qu'il y a des copies qui sont effectuées en interne, avec allocation de nouveaux objets donc.

    Pour limiter la consommation mémoire, et vu la taille de la collection, j'utiliserai le mode virtuel du DataGridView. C'est un mode spécial adapté pour les collections très large. L'idée est qu'au lieu d'allouer autant de lignes "graphiques" qu'il y a d'éléments, on utilise un évènement qui permet de retourner les valeurs pour les cellules qui sont affichées. Par contre, cela demande de revoir un peu le code...
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  6. #6
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    Bon ok, merci pour la réponse.

    Le profiling montre bien une utilisation de presque 2Go pour l'application. (et moi qui me croyais à l'abris de ce type de problème avec mes 32 Go).

    J'avais essayé le virtual mode mais j'ai rien compris en ce qui concerne l'affichage des cellule sur le this.dataGridView1.RowCount = 4;. Je suis jamais parvenu à afficher le bon nombre de ligne.

    Bref comme il s'agit d'un petit programme perso, j'ai contourné le problème en faisant l'opération en 4 fois pour travailler sur des liste plus petite...

    Merci pour l'aide.

  7. #7
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par agparchitecture Voir le message
    Le profiling montre bien une utilisation de presque 2Go pour l'application. (et moi qui me croyais à l'abris de ce type de problème avec mes 32 Go).
    L'application tourne-t-elle bien en x64 bits ? Pour le vérifier, il faut que :
    • la cible soit x64 ;
    • la cible soit AnyCPU avec la case "préférée 32 bits" décochée.


    Car s'il y a bien une limite pour la taille des objets (qui ne peuvent excéder 2Go), il n'y a pas de limite quant à la quantité de mémoire total. Donc oui, il semblerait qu'il y ait de la marge !
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  8. #8
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    alors l'application est bien en 32bits pour le moment.

    En fait je développais avec sharpdevelop en portable mais je ne suis jamais parvenus à compiler en 64 bits. Depuis heir j'ai réinstallé MVS community 2017 afin de profiler la mémoire et je n'ai pas encore réessayer de compiler en 64bits.

    Faudra que j'essaye...

    Par contre je suis preneur pour plus d'info sur le mode virtuel...

    Merci

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Il est certain que pour ce volume il faut passer par du virtuel, mais même je pense que tu as un travail à faire en amont pour préfiltrer tes données.
    En effet c'est absolument impossible pour un un humain, et donc parfaitement inutile, de pouvoir analyser le contenu de 630 000 lignes.

    Un bon programme ne devrait jamais proposer d'afficher autant de ligne, et tu te dois de forcer l'utilisation de filtre comme une plage de date, ou d'autres données métiers pertinentes.


    Souhaitant supprimer tous les doublons de manière visible, je sélectionne toute les ligne (via un bouton) sauf une avec la procédure suivante:
    Qu'entends tu de manière visible? Tu penses qu'un utilisateur va pouvoir vérifier que ce sont bien des doublons qui sont sélectionnés? Si c'est ça, c'est physiquement impossible pour 630 000 lignes!, et donc une bonne chose est de supprimer ces doublons dans ta collection avant de l'affecter à ta datagridview.

  10. #10
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par agparchitecture Voir le message
    alors l'application est bien en 32bits pour le moment.
    Dans ce cas, le problème de mémoire ne me parait guère surprenant. La solution la plus simple est de passer en 64bits. Ainsi, pas besoin de développement supplémentaire.

    Citation Envoyé par agparchitecture Voir le message
    Par contre je suis preneur pour plus d'info sur le mode virtuel...
    La MSDN regorge d'information là dessus. Le premier lien donné est une entrée avec un exemple complet. Il y a d'autres liens dans cette page qui peuvent te diriger vers moins de concret et plus de théorie.

    Après, je ne l'ai utilisé qu'une fois, et il y a un certain temps déjà. Difficile pour moi de t'en dire plus !
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  11. #11
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    @micka132
    Pour te rassurer je suis bien d'accord avec toi mais il s'agit uniquement de test et d'essais qui m'ont amener à avoir 630.000 lignes. Ca m'a permis d'apprendre encore un peu plus sur les limites d'utilisation de certain éléments.
    l'affichage des lignes étant essentiellement pour rassurer l'utilisateur (par la vue des lignes) quand au fait que le programme prend bien que des doubles et que la sélection laisse bien un seul élément conservé avant suppression.

    @ tous le monde
    le passage en 64bits résout parfaitement le problème puisque l'utilisation du profiling mémoire montre bien une augmentation jusqu'à 3,5 GO et ne bloque plus à 2GO.

  12. #12
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Citation Envoyé par agparchitecture Voir le message
    pour rassurer l'utilisateur (par la vue des lignes) quand au fait que le programme prend bien que des doubles et que la sélection laisse bien un seul élément conservé avant suppression.
    L'utilisateur est parfois le pire des problèmes . Il ne sait pas forcement ce qui est bien pour lui! En plus c'est pas parcequ'un truc est visible qu'il est forcement existant, ou inexistant.

  13. #13
    Membre régulier
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 127
    Points : 87
    Points
    87
    Par défaut
    Citation Envoyé par micka132 Voir le message
    L'utilisateur est parfois le pire des problèmes . Il ne sait pas forcement ce qui est bien pour lui! En plus c'est pas parcequ'un truc est visible qu'il est forcement existant, ou inexistant.
    ok mais le programme n'est pas forcément destiné à être distribué et n'est que pour une utilisation perso. On pourrais donc voir l'affichage comme une information de débugage. en tout cas merci pour les infos et conseils

  14. #14
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par micka132 Voir le message
    L'utilisateur est parfois le pire des problèmes
    Par experience, ce n'est pas parfois, mais très souvent !

    Je classe en deuxième position les changements "mineurs" dans le comportement d'une API. Je précise bien le comportement, pas l'API elle-même. Avant de trouver la cause du problème... Exemple pour illustrer le problème : en javascript, la méthode parseInt n'a pas le même comportement sur un firefox 17 que sur une version récente, lorsque la chaîne à convertir commence par un 0, et que la base n'est pas spécifiée.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

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

Discussions similaires

  1. [.Net 2.0] Binding avec DatagridView
    Par Mast3rMind dans le forum C#
    Réponses: 2
    Dernier message: 15/11/2007, 20h21
  2. résultat de test avec regex incompréhensible
    Par waldo2188 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/09/2007, 17h31
  3. Problème avec DataGridView et Localizable
    Par blistex dans le forum ASP.NET
    Réponses: 3
    Dernier message: 10/07/2007, 16h28
  4. VB.NET Pb de doublons avec Datagridview
    Par Igmar dans le forum Windows Forms
    Réponses: 1
    Dernier message: 02/05/2007, 14h51
  5. [c#] Travail avec datagridview.
    Par penchu dans le forum Windows Forms
    Réponses: 5
    Dernier message: 21/12/2006, 17h59

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