Problème de libération mémoire
-
vendredi 28 septembre 2012 09:26
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 ClassCe 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
Toutes les réponses
-
vendredi 28 septembre 2012 14:00
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.
- Modifié Sébastien Thevenin vendredi 28 septembre 2012 14:01
- Marqué comme réponse Aurel BeraMicrosoft Contingent Staff, Owner lundi 1 octobre 2012 09:51
-
vendredi 28 septembre 2012 14:54
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 15:43
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 SubBien à vous.
-
dimanche 30 septembre 2012 21:30Modérateur
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 -
lundi 1 octobre 2012 09:51Propriétaire
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
-
lundi 1 octobre 2012 13:54
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...

