VB.net Fuite de mémoire [Résolu]

vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 19:10 - Dernière réponse : vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention
- 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
Afficher la suite 

14 réponses

Répondre au sujet
Kevin.Ory 843 Messages postés mercredi 22 octobre 2003Date d'inscription 7 janvier 2009 Dernière intervention - 18 mai 2008 à 19:10
+3
Utile
http://forums.microsoft.com/MSDN-FR/ShowPost.aspx?PostID=3358340&SiteID=12
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Kevin.Ory
Charles Racaud 3181 Messages postés dimanche 15 février 2004Date d'inscription 9 avril 2017 Dernière intervention - 16 mai 2008 à 19:18
0
Utile
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
Commenter la réponse de Charles Racaud
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 16 mai 2008 à 19:23
0
Utile
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
Commenter la réponse de cs_casy
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 19:37
0
Utile
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!
Commenter la réponse de vfi
Kevin.Ory 843 Messages postés mercredi 22 octobre 2003Date d'inscription 7 janvier 2009 Dernière intervention - 16 mai 2008 à 19:56
0
Utile
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?
Commenter la réponse de Kevin.Ory
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 20:01
0
Utile
J'avais déjà fait les essais pour le doevents et c'est pareil!!
Commenter la réponse de vfi
cs_casy 7745 Messages postés mercredi 1 septembre 2004Date d'inscription 24 septembre 2014 Dernière intervention - 16 mai 2008 à 20:17
0
Utile
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
Commenter la réponse de cs_casy
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 20:26
0
Utile
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
Commenter la réponse de vfi
Kevin.Ory 843 Messages postés mercredi 22 octobre 2003Date d'inscription 7 janvier 2009 Dernière intervention - 16 mai 2008 à 20:44
0
Utile
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
Commenter la réponse de Kevin.Ory
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 20:55
0
Utile
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...
Commenter la réponse de vfi
Kevin.Ory 843 Messages postés mercredi 22 octobre 2003Date d'inscription 7 janvier 2009 Dernière intervention - 16 mai 2008 à 21:31
0
Utile
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...
Commenter la réponse de Kevin.Ory
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 16 mai 2008 à 21:42
0
Utile
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...
Commenter la réponse de vfi
Kevin.Ory 843 Messages postés mercredi 22 octobre 2003Date d'inscription 7 janvier 2009 Dernière intervention - 16 mai 2008 à 22:08
0
Utile
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...
Commenter la réponse de Kevin.Ory
vfi 24 Messages postés mardi 17 décembre 2002Date d'inscription 19 mai 2008 Dernière intervention - 19 mai 2008 à 11:10
0
Utile
Merci Kevin pour tout test efforts, j'ai passé mon appli en mode Realease et je n'ai plus de problème.
Commenter la réponse de vfi

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.