none
Problème de libération mémoire RRS feed

  • Question

  • Bonjour à tous,

    j'ai un souci de libération de mémoire à la fermeture d'un formulaire.

    Concrètement, ce formulaire affiche les informations d'un journal de l'observateur d'évènement dans un datagridView.

    Public Class CommHisto
        Dim EventLogHisto As System.Diagnostics.EventLog
        Dim lcdt As DataTable
        Private Sub CommHisto_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Try
                EventLogHisto = New System.Diagnostics.EventLog()
                EventLogHisto.Source = "CommServiceObserveur"
                EventLogHisto.Log = "CommServiceLog"
                EventLogHisto.EnableRaisingEvents = True
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
            lcdt = New DataTable
            Dim lcdc0 As New DataColumn
            lcdc0.ColumnName = "Date"
            Dim lcdc1 As New DataColumn
            lcdc1.ColumnName = "Type"
            Dim lcdc2 As New DataColumn
            lcdc2.ColumnName = "Message"
            Dim lcdc3 As New DataColumn
            lcdc3.ColumnName = "Id"
            lcdt.Columns.Add(lcdc0)
            lcdt.Columns.Add(lcdc1)
            lcdt.Columns.Add(lcdc2)
            lcdt.Columns.Add(lcdc3)
            For Each lce As EventLogEntry In EventLogHisto.Entries
                If (CheckBox1.Checked And lce.EntryType = EventLogEntryType.Information) _
                    Or (CheckBox2.Checked And lce.EntryType = EventLogEntryType.Warning) _
                    Or (CheckBox3.Checked And lce.EntryType = EventLogEntryType.Error) _
                    Then
                    Dim lcdr As DataRow = lcdt.NewRow
                    lcdr("Date") = lce.TimeWritten.ToShortDateString & " " & lce.TimeWritten.ToLongTimeString
                    lcdr(1) = lce.EntryType.ToString
                    lcdr(2) = lce.Message
                    lcdr(3) = lce.Category.ToString & lce.InstanceId.ToString
                    lcdt.Rows.Add(lcdr)
                End If
            Next
            lcdt.DefaultView.Sort = "Date desc"    
            DataGridView1.DataSource = lcdt
        End Sub   
       
        Private Sub Ferme() Handles Me.FormClosed
            lcdt.Clear()
            lcdt.Dispose()
            DataGridView1.Dispose()
            Me.EventLogHisto.Dispose()
        End Sub
    End Class

    Ce formulaire est ouvert par un formulaire principal. Dans ce formulaire principal, à la fermeture du fameux formulaire, j'appelle la méthode dispose de ce fameux formulaire.

    Le problème est le suivant :

    • avant l'ouverture du formulaire, je suis à peu près à 8Mo de ram occupé.
    • A l'ouverture du formulaire, je passe à peu près à 12Mo (ça dépend de la taille du journal à ce moment la)
    • A la fermeture du formulaire, je ne redescend pas à 8Mo...

    Ce qui me fais poser plusieurs questions :

    • Comment faire pour libérer complétement la mémoire à la fermeture du formulaire?
    • Y-a-t-il possibilité dans VS 2012 Ultimate de consulter la mémoire occupé pour chaque objet du projet (un peu comme l'occupation du processeur lors de l'analyse des performances)?

    Sachant que j'étais en 2010 pro jusqu'à il y a peu de temps, je ne maîtrise pas du tout les outils de tests, analyse du code etc... mais je vais m'y mettre car ça à l'air vraiment sympa...

    Si quelqu'un à des pistes, je suis preneur !

    Merci d'avance


    • Modifié bobertin vendredi 28 septembre 2012 09:27
    vendredi 28 septembre 2012 09:26

Réponses

  • Bonjour,

      Je dirais que c'est normal, le Garbage collector ne libère pas la mémoire tout de suite.

      Si tu veux vraiment forcer le Garbage Collector à libérer les déchets mémoires, tu peux faire un GC.Collect(). Mais c'est fortement déconseillé, car gourmand.

      Dans Visual Studio, normalement tu as un profiler mémoire dans le menu Déboguer. Il te permet d'enregistrer une image de la mémoire pendant l'execution de ton appli/site, et de pouvoir l'analyser après. Et même de voir les passages du Garbage Collector.



    vendredi 28 septembre 2012 14:00

Toutes les réponses

  • Bonjour,

      Je dirais que c'est normal, le Garbage collector ne libère pas la mémoire tout de suite.

      Si tu veux vraiment forcer le Garbage Collector à libérer les déchets mémoires, tu peux faire un GC.Collect(). Mais c'est fortement déconseillé, car gourmand.

      Dans Visual Studio, normalement tu as un profiler mémoire dans le menu Déboguer. Il te permet d'enregistrer une image de la mémoire pendant l'execution de ton appli/site, et de pouvoir l'analyser après. Et même de voir les passages du Garbage Collector.



    vendredi 28 septembre 2012 14:00
  • D'abord merci pour le tuyau du profiler. Dans ma version de VS, cela se trouve dans le menu Analyser.

    Cela confirme le fait que cela soit bien la lecture de du journal qui prenne beaucoup de mémoire. ...

    Ce que je ne comprends pas c'est que la mémoire reste toujours au même niveau après l'appel de la méthode dispose et du System.Gc.Collect.

    Le résultat du profilage est le suivant

    Si tu as une autre idée pour libérer cette mémoire...

    Merci d'avance



    • Modifié bobertin vendredi 28 septembre 2012 14:54
    vendredi 28 septembre 2012 14:54
  • Bonjour,

    Le Gc peut être, immédiat, dans 10 minutes, 1 heures, etc.

    Par contre l'appel de 'EmptyWorkingSet' est très efficace :

    <DllImport("psapi.dll")> _
        Public Function EmptyWorkingSet(ByVal hProcess As IntPtr) As Boolean
        End Function
    
        Public Sub Memoire_Clean()
    
             ' Déclaration des variables mémoire
            Dim MemoryUsedAfter As Long
    
            ' on prend la main du process en cours
            Dim pProcess As Process = Process.GetCurrentProcess()
    
            ' on vide le plus possible la mémoire inutilisée par le process
            Dim bRes As Boolean = EmptyWorkingSet(pProcess.Handle)
    
            If Not bRes Then
    
                ' EmptyWorkingSet a échoué...(dans certains cas cela peut échouer !)
             End If
    
            MemoryUsedAfter = Environment.WorkingSet
            Console.WriteLine(DateTime.Now & " " & "Mémoire allouée après nettoyage de la mémoire = octets " & _
                               Environment.WorkingSet)
                End Sub
    Bien à vous.


    ZGuideTV.NET - administrator/developer

    vendredi 28 septembre 2012 15:43
  • Bonjour,

    • avant l'ouverture du formulaire, je suis à peu près à 8Mo de ram occupé.
    • A l'ouverture du formulaire, je passe à peu près à 12Mo (ça dépend de la taille du journal à ce moment la)
    • A la fermeture du formulaire, je ne redescend pas à 8Mo...

    Ce comportement est normal. Tant que Windows ne hurle pas qu'il n'y a pas de mémoire le Garbage Collector ne se déclenche pas...

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0

    dimanche 30 septembre 2012 21:30
    Modérateur
  • Bonjour,

    Pouvons-nous considérer que vous avez résolu votre problème avec les scénarios proposés ? Dans l'affirmative, pourriez-vous partager avec nous la solution, afin que d'autres personnes avec le même problème puissent profiter de cette solution ? Désormais, nous marquons les solutions proposées. N'hésitez pas à revenir et supprimer la réponse marquée si la solution n’est pas correcte. Merci !

    Cordialement,

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    lundi 1 octobre 2012 09:51
  • Nous pouvons effectivement considéré le sujet clos... Je ne savais pas que windows libérer la mémoire uniquement "quand il en a besoin"...

    Merci à tous pour votre aide...

    lundi 1 octobre 2012 13:54