Programme qui utilise beaucoup trop de mémoire [Résolu]

Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 13 mai 2012 à 21:19 - Dernière réponse :
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 17:38
Bonjour,

J'ai créé un programme d'automatisation de tache en vb.net.
C'est un timer qui selectionne les les items de ma listbox les uns après les autres.
A chaque fois qu'il atteint un item, mon programme vérifie le texte contenu dans l'item et fais une action selon ce qu'il à trouvé.

Mon problème est que mon programme monte à 1.300.000 ko de mémoire :S
Comment pourrai-je éviter cela ?

Mon programme cherche essentiellement des images à l'ecran, que j'ai enregistrer à l'avance dans des fichiers png.
A chaque fois que je compare mes images, je les charges dans des picturebox......
Il cherche une vingtaine d'images.
En vous écrivant je me dis que ça dois venir de ça...
Je charge plein d'image, et assez rapidement.

Une autre piste peut-être ?

Merci d'avance.

Un peu de code pour vous aidez à comprendre.

Mon timer qui fait +1 sur lindex selectionné :

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

        If ListBoxExecute.SelectedIndex < 0 Then
            ListBoxExecute.SelectedIndex = 0
        Else
            ''compte les éléments de l'executeur
            Dim NombreDelement = ListBoxExecute.Items.Count
            ''si on arrive à la fin de l'execution....
            If (ListBoxExecute.SelectedIndex = (NombreDelement - 1)) Then
                Timer1.Enabled = False
                Timer1.Stop()

            Else
                ListBoxExecute.SelectedIndex = (ListBoxExecute.SelectedIndex + 1)
            End If
        End If

    End Sub


Et donc à chaque fois qu'un items est selectionné, voici ce qui se passe :

 Private Sub ListBoxExecute_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBoxExecute.SelectedIndexChanged
        Dim resultat As String = ""
        Me.Text = "BOSS (ligne n°" & ListBoxExecute.SelectedIndex & ")"

        If (Timer1.Enabled = True) Then

            If InStr(ListBoxExecute.SelectedItem, "<Clique> ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                positionducurseuretclique()
            ElseIf InStr(ListBoxExecute.SelectedItem, "<DoubleClique> ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                positionducurseuretdoubleclique()
            ElseIf InStr(ListBoxExecute.SelectedItem, " ") > 0 Then
                Pause()
            ElseIf InStr(ListBoxExecute.SelectedItem, " ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                positionducurseuretappui()
            ElseIf InStr(ListBoxExecute.SelectedItem, "<Relacher> ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                positionducurseuretlache()
            ElseIf InStr(ListBoxExecute.SelectedItem, "<Texte> ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                SendStringKeys(Replace(ListBoxExecute.SelectedItem, "<Texte> ", ""))
            ElseIf InStr(ListBoxExecute.SelectedItem, "<Goto> ") > 0 Then
                Dim Debut As String
                Dim Fin As String
                Dim d As String = "<Goto> " 'd=chaine début
                Debut = InStr(1, ListBoxExecute.SelectedItem, d)  ' Position du <
                Fin = InStr(1, ListBoxExecute.SelectedItem, ".")   ' Position du <
                ListBoxExecute.SelectedIndex = Mid$(ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length)
            ElseIf InStr(ListBoxExecute.SelectedItem, "<ChercheImage> ") > 0 Then
                Timer1.Enabled = False
                Timer1.Stop()
                traitement()
            End If
        End If

    End Sub


J'ai pas pris soin de modifier les commentaires selon mon code mais il n'y pas grand chose à commenter.
Afficher la suite 

Votre réponse

14 réponses

Meilleure réponse
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Contributeur
Dernière intervention
11 avril 2018
- 13 mai 2012 à 21:54
3
Merci
Bonjour,
je ne sais pas (ni ne tiens à le savoir) le but d'un tel mécanisme.
Ce qui est par contre assez évident, c'est que ce n'est pas le code montré qui "bouffe" ta mémoire, mais une ou plusieurs des procédures qui sont appelées par le timer !
Si, comme tu l'exposes, certaines de ces procédures chargent une image, ma foi ... c'est comme les gouttes d'eau qui, se réunissant, finissent par former une rivière (et les rivières, elles, peuvent connaître des crues ).

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ

Merci ucfoutu 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de ucfoutu
Meilleure réponse
Messages postés
14010
Date d'inscription
samedi 29 décembre 2001
Dernière intervention
28 août 2015
- 13 mai 2012 à 22:01
3
Merci
Salut

Oui, la goutte d'eau qui met le feu aux poudres !
Regarde voir si tu charges des objets sans penser à les décharger proprement. C'est ce genre de manœuvres qui créent les "fuites de mémoires".

On 'double-clique', mais l'objet s'appelle un 'double-clic'

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)

Merci cs_Jack 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 86 internautes ce mois-ci

Commenter la réponse de cs_Jack
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 13 mai 2012 à 21:21
0
Merci
Je dois rajouter que quand il detecte l'une de ces chaines, il lance une fonction différente pour chaque chaine, ces fonction se trouve en grande partie dans des modules.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 13 mai 2012 à 23:35
0
Merci
Bonsoir à vous deux et merci pour vos réponses.
Je penses que jack à mis le doigt dessus !
Je n'ai pas encore essayé, et pour ce soir je m'arrête, mais effectivement, je charge des images dans des picturebox mais je ne les déchargent pas....
C'est sans doute la raison pour laquelle mon programme utilise autant de mémoire.
Je vérifie ça demain et je vous tiens au courant !

Merci encore.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 13 mai 2012 à 23:36
0
Merci
En ce qui concerne le <DoubleClique>, si mon programme lis DoubleClique, il va bien effectuer le double clique.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 13 mai 2012 à 23:58
0
Merci
J'ai dis jack mais c'est ucfoutu qui avais mis le doigt dessus :p
J'ai tellement bidouiller ce soir que même s'il ne trouve pas l'image, il clique, grrr.
Je suis dessus depuis ce matin et je n'y comprend plus rien !
Demain je revois tout ça mais je pense fortement que vous avez tout les deux raisons, l'accumulation d'images.
Sinon au lieu de charger à chaque fois les images qui sont dejà enregistrer au format .png, ne serai t-il pas possible de les charger en variable, et de loader uniquement les images de l'écran dans une picturebox et les comparer à limage charger dans la variable sans passer par une picturebox ?
J'en suis déjà à l'optimisation alors qu'il n'est pas encore opérationnel.
Commenter la réponse de KcHeY
- 14 mai 2012 à 03:25
0
Merci
Bonjour,

Et puis, pour couronner le tout, le format PNG n'a pas été inventé pour restreindre l'utilisation de la mémoire, loin de là.
Commenter la réponse de Utilisateur anonyme
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 12:20
0
Merci
Bonjour à vous,

ucfoutu, pour en revenir au but de ce programme, c'est comme je l'ai indiqué au début de mon poste, un programme d'automatisation, c'est à dire que je peux reproduire des actions répétitive, je sais que de tel programme existe mais je voulais m'en créer un perso.

Bon je viens de tester le déchargement d'image dans mes picturebox, et la mémoire continu à s'accumuler.

Je vous montre mon traitement d'image, peut-être seriez-vous me dire si mon problème de mémoire viens de là.

Donc la je récupère le liens de l'image a charger dans une picturebox, et les coordonnées de l'image à récupérer sur l'écran.
Module TraitementChercheImage
    Function traitement()
        Boss.Timer1.Enabled = False
        Boss.Timer1.Stop()
        Dim Debut As String
        Dim Fin As String
        Dim d As String = "<ChercheImage> :" 'd=chaine début
        Debut = InStr(1, Boss.ListBoxExecute.SelectedItem, d)  ' Position du <
        Fin = InStr(1, Boss.ListBoxExecute.SelectedItem, ";")   ' Position du <

        LoadPicturee.PictureBox1.Image = Image.FromFile(Mid$(Boss.ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length))
        Dim Bounds As Rectangle
        Dim Capture As System.Drawing.Bitmap
        Dim Graph As Graphics
        Bounds = Screen.PrimaryScreen.Bounds
        Capture = New System.Drawing.Bitmap(Bounds.Width, Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        Graph = Graphics.FromImage(Capture)
        Graph.CopyFromScreen(Bounds.X, Bounds.Y, 0, 0, Bounds.Size, CopyPixelOperation.SourceCopy)

        d = "début x=" 'd=chaine début
        Debut = InStr(1, Boss.ListBoxExecute.SelectedItem, d)  ' Position du <
        Fin = InStr(1, Boss.ListBoxExecute.SelectedItem, ",début y=")   ' Position du <debutx =
        Dim debutx = Mid$(Boss.ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length)

        d = "début y=" 'd=chaine début
        Debut = InStr(1, Boss.ListBoxExecute.SelectedItem, d)  ' Position du <
        Fin = InStr(1, Boss.ListBoxExecute.SelectedItem, ",fin x=")   ' Position du <debutx =
        Dim debuty = Mid$(Boss.ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length)

        d = "fin x=" 'd=chaine début
        Debut = InStr(1, Boss.ListBoxExecute.SelectedItem, d)  ' Position du <
        Fin = InStr(1, Boss.ListBoxExecute.SelectedItem, ",fin y=")   ' Position du <debutx =
        Dim finx = Mid$(Boss.ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length)

        d = "fin y=" 'd=chaine début
        Debut = InStr(1, Boss.ListBoxExecute.SelectedItem, d)  ' Position du <
        Fin InStr(1, Boss.ListBoxExecute.SelectedItem, ",.")   ' Position du <debutx
        Dim finy = Mid$(Boss.ListBoxExecute.SelectedItem, Debut + d.Length, Fin - Debut - d.Length)

        Dim w1 = (finx - debutx)
        Dim h1 = (finy - debuty)

        LoadPicturee.PictureBox2.Image = RognImage(Capture, debutx, debuty, w1, h1)

        Dim cheminImage1 As Image = LoadPicturee.PictureBox1.Image

        Dim cheminImage2 As Image = LoadPicturee.PictureBox2.Image

        Dim ResultImage As String = ComparerDeuxImages((LoadPicturee.PictureBox1.Image), (LoadPicturee.PictureBox2.Image), False, 25, 5)
        If ResultImage = "True" Then
            LoadPicturee.PictureBox1.Image.Dispose()
            LoadPicturee.PictureBox2.Image.Dispose()
            Boss.Timer1.Enabled = True
            Boss.Timer1.Interval = 500
            Boss.Timer1.Start()
        Else


            LoadPicturee.PictureBox1.Image.Dispose()
            LoadPicturee.PictureBox2.Image.Dispose()
            Boss.Timer1.Enabled = True
            Boss.Timer1.Interval = 500
            Boss.Timer1.Start()
            Boss.ListBoxExecute.SelectedIndex = Boss.ListBoxExecute.SelectedIndex + 5
        End If


    End Function

    Private Function RognImage(ByVal ImaSource As Bitmap, ByVal xPixelDep As Int32, ByVal yPixelDep As Int32, ByVal xPixelTotal As Int32, ByVal yPixelTotal As Int32) As Bitmap
        Dim nouvImage As New Bitmap(xPixelTotal, yPixelTotal)
        Dim graph As Graphics = Graphics.FromImage(nouvImage)
        Dim rect As New Rectangle(0, 0, xPixelTotal, yPixelTotal)
        graph.DrawImage(ImaSource, rect, xPixelDep, yPixelDep, xPixelTotal, yPixelTotal, GraphicsUnit.Pixel)
        Return nouvImage
    End Function
End Module



Et la c'est le traitement d'image: (source récupéré sur ce site il me semble)

Module CompareImage

#Region "Comparer deux images"
    'PARAMETRES: 
    'verifierProportions: si ce parametre est à true, on différencie les images de proportions différentes (ex: 9*10 et 10*10) -tolérance de 1%
    'TailleEchantillon: définit la taille de la miniature qui sera utilisée pour la comparaison. La fonction est plus rapide sur un echantillon proche de 1 et plus précise (et moins tolérante) si l'échantillon est loin de 1. Par experience 25 donne des résultats satisfaisants pour moi.
    'toleranceDeCouleur: nombre entre 0 et 255 qui définit la différence de couleur autorisée sur chaque canal

    Public Function ComparerDeuxImages(ByVal image1 As Image, ByVal image2 As Image, Optional ByVal verifierProportions As Boolean True, Optional ByVal TailleEchantillon As Integer 25, Optional ByVal toleranceDeCouleur As Byte = 5) As Boolean
        'Je fais un premier test rapide de couleur et de forme pour débusquer les images très différentes:
        If FonctionComparaisonImages(image1, image2, verifierProportions, 1, toleranceDeCouleur) = False Then
            Return False '-->elles sont tres différentes
        Else
            'si je les trouve proche, je confirme par un test plus précis, mais sans revérifier les proportions (déja fait si demandé)
            If FonctionComparaisonImages(image1, image2, False, TailleEchantillon, toleranceDeCouleur) = False Then
                Return False '--> elles ne sont pas suffisemment proches pour être considérées identiques
            Else
                Return True '--> elles sont semblables
            End If
        End If
    End Function

    Private Function FonctionComparaisonImages(ByVal image1 As Image, ByVal image2 As Image, Optional ByVal verifierProportions As Boolean True, Optional ByVal TailleEchantillon As Integer 25, Optional ByVal toleranceDeCouleur As Byte = 5) As Boolean

        'vérifier que les images ont les memes proportions
        If verifierProportions = True Then
            If Math.Abs(image1.Height / image2.Height - image1.Width / image2.Width) >= 0.01 Then Return False
        End If

        'vérifier la précision:
        If TailleEchantillon < 1 Then TailleEchantillon = 1
        If TailleEchantillon > image1.Width Then TailleEchantillon = image1.Width
        If TailleEchantillon > image2.Width Then TailleEchantillon = image2.Width
        If TailleEchantillon > image1.Height Then TailleEchantillon = image1.Height
        If TailleEchantillon > image2.Height Then TailleEchantillon = image2.Height

        'On fait une miniature carrée des deux images que l'on va comparer
        'IMAGE1
        Dim Thumb1 As New Bitmap(TailleEchantillon, TailleEchantillon)
        Dim Graph1 As Graphics = Graphics.FromImage(Thumb1)
        Graph1.InterpolationMode = Drawing2D.InterpolationMode.Low
        Graph1.DrawImage(image1, New Rectangle(0, 0, TailleEchantillon, TailleEchantillon))
        Graph1.Dispose()

        'IMAGE2
        Dim Thumb2 As New Bitmap(TailleEchantillon, TailleEchantillon)
        Dim Graph2 As Graphics = Graphics.FromImage(Thumb2)
        Graph2.InterpolationMode = Drawing2D.InterpolationMode.Low
        Graph2.DrawImage(image2, New Rectangle(0, 0, TailleEchantillon, TailleEchantillon))
        Graph2.Dispose()

        Dim temp1 As Integer
        Dim temp2 As Integer
        'pour chaque pixel des images miniatures on vérifie que les couleurs RGB sont identiques à la toleranceDeCouleur près
        For x As Integer = 0 To TailleEchantillon - 1
            For y As Integer = 0 To TailleEchantillon - 1
                temp1 = (Thumb1.GetPixel(x, y).B)
                temp2 = (Thumb2.GetPixel(x, y).B)
                If Math.Abs(temp1 - temp2) > toleranceDeCouleur Then Return False
                temp1 = (Thumb1.GetPixel(x, y).G)
                temp2 = (Thumb2.GetPixel(x, y).G)
                If Math.Abs(temp1 - temp2) > toleranceDeCouleur Then Return False
                temp1 = (Thumb1.GetPixel(x, y).R)
                temp2 = (Thumb2.GetPixel(x, y).R)
                If Math.Abs(temp1 - temp2) > toleranceDeCouleur Then Return False
            Next
        Next

        'si on est pas encore sorti de la fonction les images sont similaires:
        Return True
    End Function

#End Region


End Module


Cela suffit pour décharger des images ?

LoadPicturee.PictureBox1.Image.Dispose()
LoadPicturee.PictureBox2.Image.Dispose()


Merci pour votre temps.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 13:29
0
Merci
Je load les images dans une form créé exprès pour.
Donc en principe, après mon traitement, formconcercné.Dispose devrais suffir non ?
Et bien ma mémoire monte toujours.
Les modules doivent t-ils être déchargé ?
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 14:40
0
Merci
J'ai fait ça :

  If ResultImage = "True" Then
            LoadPictureee.Close()
            LoadPictureee.Dispose()
            Boss.TextBox1.Text += "mémoire libéré"
            Thread.Sleep(500)
            Boss.Timer1.Enabled = True
            Boss.Timer1.Interval = 500
            Boss.Timer1.Start()
        Else
            LoadPictureee.Close()
            LoadPictureee.Dispose()
            Boss.TextBox1.Text += "mémoire libéré"
            Thread.Sleep(500)
            Boss.Timer1.Enabled = True
            Boss.Timer1.Interval = 500
            Boss.Timer1.Start()
            Boss.ListBoxExecute.SelectedIndex = Boss.ListBoxExecute.SelectedIndex + 5
        End If


LoadPicture étant le nom de la form ou se trouve les deux picturebox.
Boss.TextBox1.Text += "mémoire libéré"
Mon textbox est bien rempli par cette ligne à chaque passage, donc la fermeture de la forme et la liberation de mémoire est bien éffectué ?
Si oui, le problème viens d'ailleurs car la mémoire ne descend pas.
En tout cas ça viens bien de la fonction compare image car si je ne met pas ces actions dans ma listbox, la mémoire est a 7000, par contre elle monte quand meme petit à petit.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 15:05
0
Merci
Ce ne serai pas les déclarations de variables entre les sub ?
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 15:14
0
Merci
Je suis désolé d'écrire sans attendre les réponses, jai déplacé le maximum de variable en haut de mon code, est effectivement, mon programme monte à 200.000 puis redescend à 50.000, donc ça m'as l'air d'un bon début, mais la je cherche que deux image.. faut que je vois avec plus d'images.
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 17:38
0
Merci
Bon mon prog demarre à 50.000 et y redescend vers les 300.000, mais ça varie assez rapidement, c'est pas mauvais pour le pc ? monter, descendre, monter, descendre etc......

Bon je vais mettre résolu je pense que ça va le faire :p
Commenter la réponse de KcHeY
Messages postés
261
Date d'inscription
dimanche 23 mai 2004
Dernière intervention
22 septembre 2012
- 14 mai 2012 à 17:38
0
Merci
Merci pour tout !
Commenter la réponse de KcHeY

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.