vfi
Messages postés24Date d'inscriptionmardi 17 décembre 2002StatutMembreDernière intervention19 mai 2008
-
16 mai 2008 à 19:10
vfi
Messages postés24Date d'inscriptionmardi 17 décembre 2002StatutMembreDernière intervention19 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
vfi
Messages postés24Date d'inscriptionmardi 17 décembre 2002StatutMembreDernière intervention19 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!
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_casy
Messages postés7741Date d'inscriptionmercredi 1 septembre 2004StatutMembreDernière intervention24 septembre 201440 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.
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 200911 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
vfi
Messages postés24Date d'inscriptionmardi 17 décembre 2002StatutMembreDernière intervention19 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...
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 200911 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...
vfi
Messages postés24Date d'inscriptionmardi 17 décembre 2002StatutMembreDernière intervention19 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...
Kevin.Ory
Messages postés840Date d'inscriptionmercredi 22 octobre 2003StatutMembreDernière intervention 7 janvier 200911 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...