|
| Inicio → WINDEV 2025 → Perte de mémoire : Attention ! les instances d'objets ne se détruisent pas toujours ! |
| Perte de mémoire : Attention ! les instances d'objets ne se détruisent pas toujours ! |
| Iniciado por christophe.pradel, 20,dic. 2018 17:33 - 6 respuestas |
| |
| | | |
|
| |
| Publicado el 20,diciembre 2018 - 17:33 |
Bonjour à tous
Je viens de mettre le doigt sur ce que je considère comme un BUG jusqu'à ce qu'on m'explique le problème :
A l'origine, je constatais qu'au fur et à mesure de l'utilisation de mon programme, la place mémoire occupée par l'exécutable enflait à chaque requête, jusqu'à planter le programme.
Après quelques recherches, j'ai trouvé le cœur du problème dans la gestion des Objets, qui, dans une circonstance bien particulière, ne se libèrent jamais après utilisation
Le mieux, c'est de voir un exemple concret :
Soit une ClasseA définie comme suit :
ClasseA est une Classe m_sProp1 est une chaîne m_nProp2 est un entier m_tabClasseB est un tableau de ClasseB dynamique FIN
PROCÉDURE Constructeur()
Trace("Constructeur ClasseA")
PROCÉDURE Destructeur()
Trace("Destructeur ClasseA")
Soit une ClasseB définie comme suit :
ClasseB est une Classe m_sProp1 est une chaîne m_nProp2 est un entier ObjetA est un ClasseA dynamique FIN
PROCÉDURE Constructeur()
Trace("Constructeur ClasseB")
PROCÉDURE Destructeur()
Trace("Destructeur ClasseB")
Soit le code suivant :
clClasseA est un ClasseA()
POUR i = 1 À 3 clClasseB est un ClasseB() clClasseB.ObjetA <- clClasseA clClasseA.m_tabClasseB.Ajoute(clClasseB) FIN
Si on regarde la trace, on voit çà :
Constructeur ClasseA Constructeur ClasseB Constructeur ClasseB Constructeur ClasseB
Vous avez bien vu ! les objets ne sont jamais détruits !
Si j'enlève du code le lien entre l'objet A et les objets B:
clClasseA est un ClasseA()
POUR i = 1 À 3 clClasseB est un ClasseB() // clClasseB.ObjetA <- clClasseA // Ligne à l'origine des problèmes clClasseA.m_tabClasseB.Ajoute(clClasseB) FIN
Dans ce cas, la trace est plus conforme :
Constructeur ClasseA Constructeur ClasseB Constructeur ClasseB Constructeur ClasseB Destructeur ClasseA Destructeur ClasseB Destructeur ClasseB Destructeur ClasseB
Et mes tests ont montré que sans le lien, je n'ai plus d'inflation de mémoire perdue.
J'ai fais le test en W23 et W24 avec les mêmes conclusions
Quelqu'un peut-il me confirmer qu'il constate le même phénomène ? |
| |
| |
| | | |
|
| | |
| |
| Publicado el 20,diciembre 2018 - 18:12 |
Bonjour, En automatique c'est le rôle du garbage collector "Ramasse miette" de détruire les objets, mais pour un code plus propre, il est toujours préférable de forcer la libération de ces objets lorsque l'on en a plus besoin. Syntaxe1
libérer 'Nom de l'Objet' Syntaxe 2
'Nom de l'Objet' = Null |
| |
| |
| | | |
|
| | |
| |
| Publicado el 21,diciembre 2018 - 09:40 |
Merci pour ta réponse, mais il s'agit d'un contournement.
Que la mémoire soit récupérée par un garbage collector, pas de problème, mais le plus grave, c'est que le code du destructeur ne soit pas systématiquement appelé quand l'objet concerné n'est plus utilisé.
J'ai pris mon parti de ne plus utiliser de références croisées en attendant la correction (s'il y en a une), mais bon, c'est un cailloux dans la chaussure de tout programmeur objet. |
| |
| |
| | | |
|
| | |
| |
| Publicado el 21,diciembre 2018 - 09:54 |
Bonjour
Remplace
ObjetA est un ClasseA dynamique
PAR
ObjetA est un ClasseA dynamique <Faible>
Bon dev Marc Fastré www.marc-fastre.be |
| |
| |
| | | |
|
| | |
| |
| Publicado el 21,diciembre 2018 - 10:19 |
| |
| |
| | | |
|
| | |
| |
| Publicado el 21,diciembre 2018 - 11:41 |
Merci Marc et Elian ! Une vrai réponse d'experts !
Non seulement c'est précis, mais j'ai le lien vers une partie de la doc que je n'avais pas vue
J'ai déjà pu tester avec succès la solution proposée par Marc
Je vais tester la piste proposée par Elian,
En tout cas, merci pour votre aide, j'espère que vous êtes régulièrement sur le forum à attraper les bouteilles à la mer  |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 96 mensajes |
|
| Publicado el 21,diciembre 2018 - 12:04 |
+1 pour les notions de référence forte et faible et ravi d'avoir découvert l'extension force Destructeur.
J'en profite pour rajouter un détail. Le Garbage collector ne garantit pas l'exécution du destructeur immédiatement après le déréférencement de la dernière instance utilisée, il peut se faire beaucoup plus tard.
Quant à l'utilisation du mot clé Libérer, il ne sera nécessaire que sur l'objet A. Les objets B seront récupérés ensuite par le garbage collector puisqu'ils ne seront plus référencés.
Bon courage pour la suite !
-- Johjo aka Jonathan Laurent
Codez mieux ! Codez plus vite !
Mon blog sur WinDev : http://www.ytreza.org Me contacter sur slack (wx-community) : https://frama.link/BoBD0SY0 Faîtes moi un ping : http://www.ytreza.org/fr/services/ping-sur-forum |
| |
| |
| | | |
|
| | | | |
| | |
|