VB.net Fuite de mémoire

Résolu
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008 - 16 mai 2008 à 19:10
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008 - 19 mai 2008 à 11:10
Bonjour,

J'ai un proble de fuite de mémoire très important.
Apparemment c'est l'utilisation de INotifyPropertyChanged qui pose problème (Voir code ci-dessous)

Quelqu'un à une solution pour résoudre ce problème?

Merci

Imports

System.ComponentModel

Public
Class Form1
   
Private
Sub Button1_Click(
ByVal sender
As System.Object,
ByVal e
As System.EventArgs)
Handles Button1.Click
      
Me.BackColor = Color.Aquamarine
      Application.DoEvents()
      
Do
         Dim a1
As Demo =
New Demo
         Application.DoEvents()
      
Loop
   End
Sub

   Private
Sub Form1_FormClosed(
ByVal sender
As
Object,
ByVal e
As System.Windows.Forms.FormClosedEventArgs)
Handles
Me.FormClosed

      End
   End
Sub
End
Class

Public
Class Demo

Implements INotifyPropertyChanged

Private mchaine
As
String =
String.Empty

Public
Event PropertyChanged
As PropertyChangedEventHandler
Implements INotifyPropertyChanged.PropertyChanged

   
Private
Sub NotifyPropertyChanged(
ByVal info
As
String)

      RaiseEvent PropertyChanged(
Me,
New PropertyChangedEventArgs(info))

End
Sub

   Public
Property chaine()
As
String
     Get
      Return
Me.mchaine

     End
Get
     Set(
ByVal value
As
String)

         If
Not (value = mchaine)
Then
            Me.mchaine = value
            NotifyPropertyChanged(
"chaine")

         End
If
      End
Set
   End
Property
End
Class

14 réponses

Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
18 mai 2008 à 19:10
3
Utilisateur anonyme
16 mai 2008 à 19:18
Salut,

Un peu évident non ^^
     Do
         Dim a1 As Demo = New Demo
         Application.DoEvents()
      Loop
Une boucle sans fin et une création d'instance à chaque passage.

__________
  Kenji
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
16 mai 2008 à 19:23
Alors là, tu viens d'inventer la fonction à créer un dépassement de pile

Tu dois avoir un beau message d'erreur en quelques secondes, je pense.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #    http://aide-office-vba.monforum.com/index.php
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
16 mai 2008 à 19:37
La boucle do loop est la seulement pour montrer mon problème.
Je voudrais savoir comment libérer la mémoire.
Si je ne déclare pas de INotifyPropertyChanged le programme tourne sans problème!
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
16 mai 2008 à 19:56
Alors là, tu viens d'inventer la fonction à créer un dépassement de pile




Tu dois avoir un beau message d'erreur en quelques secondes, je pense.




Que je sache, un objet qui n'est plus utilisé est libéré automatiquement en .NET. Et ce Dim n'est plus utilisé à la fin de la loop.

Et sans le DoEvents ça donne quoi?
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
16 mai 2008 à 20:01
J'avais déjà fait les essais pour le doevents et c'est pareil!!
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
16 mai 2008 à 20:17
Kevin > "...Et ce Dim n'est plus utilisé à la fin de la loop..."

Sauf que tel qu'est le code, la fin du loop n'est jamais atteinte puisque c'est une boucle sans fin.

vfi > "...

La boucle do loop est la seulement pour montrer mon problème...."

Sauf que là, ta boucle ne montre pas le problème, au contraire, elle le masque par un autre.
Peut-etre que tu as peut-etre une fuite mémoire à cause du INotifyPropertyChanged, mais avec ce code, la fuite mémoire que tu vois est celle de ta boucle infinie.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #    http://aide-office-vba.monforum.com/index.php
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
16 mai 2008 à 20:26
Et pourquoi dès que j'enlève ce fameux INotifyPropertyChanged Aucune fuite n'apparait?

Si je remplace de do loop par  le problème est le même, le programme augmente en mémoire, le GC devrait normalement faire du ménage non!

For i As Integer = 1 To 100
      Dim a1 As Demo = New Demo
      'Application.DoEvents()
 Next
0
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
16 mai 2008 à 20:44
Casy> Quand je dis la fin du Loop, je voulais dire lorsque le Loop recommence.
Dsl de te contredire, mais je ne suis pas d'accord (d'ailleur j'ai testé): Tout ce qui est déclaré a l'intérieur d'une boucle ou d'une condition, est innacessible à l'extérieur du bloc en question et est détruit dès sa sortie.
Des boucles sans fin de ce genre sont courrament utilisé dans certains programmes, comme les jeux DirectX ou des serveurs, et ne pose aucuns probèmes.
Aucun problème avec ça, j'ai fais la boucle environ un million de fois, CPU à 100% mais mémoire stable:

 
  Do While Not exitLoop
            Dim item1 As New ListViewItem
            Dim item2 As New Button
            Dim item3 As New Bitmap(2, 2)
            Dim item4 As New Form
            Dim item5 As New Xml.XmlDocument
            cnt += 1
            Application.DoEvents()
     Loop

Moi je pense aussi que ca vient de l'événement. Je crois qu'un AddHandler utilise d'autres threads que le principal, le problème viens peut-être de la même si aucun EventHandler n'est créé dans ton code... Je vais creuser
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
16 mai 2008 à 20:55
Kevin >  Je suis entièrement d'accord avec toi, j'ai fait tourné mon appli sans INotifyPropertyChanged plusieurs minutes et la CPU est restée entièrement stable.
Le problème ne viens pas de là.
Actuellement je génère des évènements dans la classe Demo mais aucun thread n'y est abonné. Le code que j'ai mis dans mon premier post est complet.
A suivre...
0
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
16 mai 2008 à 21:31
Effectivement, c'est bien l'événement qui produit cette "fuite" de mémoire.
Même comme ça elle se produit:

Public Class Demo
      Public Event PropertyChanged(ByVal u As Integer)
End Class

C'est tout de même très étonnant. Il semblerait que l'événement ne soit pas détuit à la destruction de la classe mais seulement à la fermeture du programme. Bug ou impossible de faire autrement? je ne sais pas, mais en tout cas c'est nul.
Il faut donc faire ça autrement, avec un Delegate ca devrait fonctionner:

C'est plus long à coder et ça ne permet pas de capturer l'événement dans plusieurs Sub différente, mais ça fonctionne:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Label1.Text = "Started"

        Dim cnt As Long = 0
        ExitLoop = False
        Do While Not ExitLoop
            Dim a1 As Demo = New Demo
            a1.SetPropertyChangedCallback(AddressOf PropertyChanged)
            cnt += 1
            Application.DoEvents()
        Loop

        Me.Label1.Text = cnt
    End Sub

    Private Sub PropertyChanged(ByVal Sender As Object, ByVal e As PropertyChangedEventArgs)

    End Sub

    Private ExitLoop As Boolean = False
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click, Me.FormClosing
        ExitLoop = True
    End Sub
End Class

Public Class Demo
    Public Delegate Sub PropertyChanged(ByVal Sender As Object, ByVal e As PropertyChangedEventArgs)

    Private _PropertyChangedCallback As PropertyChanged
    Public Sub SetPropertyChangedCallback(ByVal Callback As PropertyChanged)
        _PropertyChangedCallback = Callback
    End Sub

    Protected Sub NotifyPropertyChanged(ByVal info As String)
        _PropertyChangedCallback.Invoke(Me, New PropertyChangedEventArgs(info))
    End Sub
End Class

Mais tout de même, il y a un problème qq part. Je dis ça car les objets que j'ai utilisé dans le test de mon message précédent ont aussi des événements, pourtant ça ne provoque pas cette fuite de mémoire. Quelle est la technique des développeur de Microsoft? Détruire l'événement dans Finalize? vais voir si c'est possible...
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
16 mai 2008 à 21:42
Merci pour ton aide, je vais voir si je peux greffer ton code dans le mien, sinon moi aussi je cherches toujours une solution.
Je te tiendrais au courant si je trouve quelque chose...
0
Kevin.Ory Messages postés 840 Date d'inscription mercredi 22 octobre 2003 Statut Membre Dernière intervention 7 janvier 2009 11
16 mai 2008 à 22:08
Herf, je vois pas comment on peut éviter ça. J'ai envie de dire que c'est surement un bug de VisualBasic, puisque les objets du framework n'ont pas ce problème.

Une question à poser sur le forum de Microsoft on dirait...
0
vfi Messages postés 24 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 19 mai 2008
19 mai 2008 à 11:10
Merci Kevin pour tout test efforts, j'ai passé mon appli en mode Realease et je n'ai plus de problème.
0
Rejoignez-nous