RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN RIEN

florenth - 14 juin 2007 à 12:05
417 Messages postés 3 Date d'inscription lundi 27 novembre 2006 Statut Membre Dernière intervention 4 juillet 2008 - 9 juil. 2007 à 12:20
417 Messages postés 3 Date d'inscription lundi 27 novembre 2006 Statut Membre Dernière intervention 4 juillet 2008
9 juil. 2007 à 12:20
MERCI
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
15 juin 2007 à 00:20
... ou alors tu programme sur une calculette !

En tout cas le code est tres interressant et les explications encore plus .

Merci

Ciao
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
15 juin 2007 à 00:04
@ florent : "Et encore, Windows arrive bien à en faire tout seul des fuites..."
Peut etre n'existe il pas que windows ...
T'a tout compris Cirec !
Oui, le méthode 2 est la meilleure je trouve, même si je ne fais jamais comme ça ! lol (en même temps, j'en ai eu l'idée y'a deux jours)

"@Forman: "Comment ne JAMAIS avoir de fuites de mémoire:"
-ne jamais faire de programmation. lol"

> Et encore, Windows arrive bien à en faire tout seul des fuites...
Donc correction: ne pas toucher à un ordi !! Mais là, ça devient difficile... ^^
Utilisateur anonyme
14 juin 2007 à 17:35
J'avais bien compris le principe des fuites de mémoires ... lol

ce que je voulais dire c'est qu'en procédant différement il y avait moins de fuites.

Bien sur si tu coches la case il n'y a pas de fuite ... et dans ma procedure non plus.

Pour l'ordre création et d'appel, il est vrai que l'on a pas toujours le choix ... mais quand c'est possible c'est quand même plus "sécurisé" et le résultat des testes le démontre.

Tu me demandais quelle était ma facon de faire ... je te donne ma réponse en fonction du code ;)

Ce qu'il faut retenir c'est :
Si on évite de déclancher une exeption dans le Destructeur, les Méthodes 2, 3 et 4 sont bonnes
avec une préférence pour la 2ème qui est plus simple d'utilisation.

Un superbe exemple, très bien fait, qui offre, à mon avis, bien plus
qu'un "simple" exemple sur les fuites de mémoires ...

Bravo

@Forman: "Comment ne JAMAIS avoir de fuites de mémoire:"
-ne jamais faire de programmation. lol

@+
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
14 juin 2007 à 17:26
Si je me souviens bien pour la DLL, j'avais un problème avec une méthode virtuelle qui appelait le destructeur (mais ça fait un moment). J'en avais conclu que le problème venait de ce que l'EXE utilisait son code à lui pour détruire l'instance, et donc qu'il libérait lui-même de la mémoire qui avait été allouée dans la DLL (plantage du memory manager, donc). J'avais Delphi 6 à ce moment là, peut-être que le problème venait de là?

Ah oui, et la classe descendante était implémentée uniquement dans la DLL bien entendu (l'EXE n'en avait mention nulle part).
@forman: en effet, les interfaces sont mieux faites pour cela. En plus, le reference-counting qui va avec est bien pratique...
Mais à part ça, j'ai essayé de faire planter une classe depuis une dll avec des méthodes virtuelles, dynamiques, certaines surchargées d'autres non et j'ai pas réussi à me faire insulter par Windows !

Pour ta technique anti-fuite, c'est vrai que c'est radical mais tu oublies:
- Ne pas se servir de fichiers
- Et encore moins d'objets Windows (donc tout faire en appli console car une App GUI a des fenêtres ^^ ... ===> pff la galère)
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
14 juin 2007 à 16:52
@florenth: effectivement, c'était pour un plugin que j'avais fait essayé de faire ça (plus spécifiquement un skin chargé dynamiquement depuis une DLL). J'avais fini par abandonner les classes et j'étais passé aux interfaces (qui elles fonctionnent sans problème).
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
14 juin 2007 à 16:49
Comment ne JAMAIS avoir de fuites de mémoire:
-n'utiliser que des types entiers, flottants, shortstring ou tableaux de taille fixe
-n'utiliser que des record (dont les membres sont soit des types mentionnés précédemment, soit des record)
-ne jamais faire d'allocation dynamique

Bon d'accord, je sors
Pour l'histoire de ta technique qui est soi-disant plus performante que la mienne:
En fait il s'agit juste d'un ordre de déclenchement des exceptions. Tu remarqueras que dans mes trois méthodes de test, je suis le même protocole: je construit les trois objets, les utilise et enfin les détruit.

Si tu modifies cet ordre, tu obtiens des résultats qui ne sont pas comparables. En l'occurrence, ta méthode 4 est l'équivalente de ma méthode 3 sauf que tu utilises les objets juste après leur construction, et non pas une fois que les trois objets ont été crées.
Du coup, les deux tiers des bugs de destructeurs sont évités. Mais l'intérêt est limité puisqu'en programmation, tu ne choisis pas vraiment l'endroit où tu utilises tes objets. Il faut respecter une certaine logique (je ne t'apprend rien ^^).

L'ordre des étapes de mes fonctions de tests sont faites de façon à être les plus sensibles aux erreurs.
En espérant m'être fait comprendre... lol
Héhé, mais c'est normal qu'il y ait des fuites de mémoires ! Tant que le pourcentage de réussite n'atteint pas 100%, c'est que justement, il y en a !

Mais tu remarqueras que pour les méthodes deux et trois, si tu coches la case "aucun destructeur foireux" il n'y a plus rien. D'où le fait que les destructeurs ne doivent pas renvoyer d'exceptions.

C'est cela qui m'a servi d'appui pour mon constat .
Utilisateur anonyme
14 juin 2007 à 16:07
j'utilise aussi la méthode N°1 ... bien souvant elle est siffisante

Mais quand j'ai besoin de plus de "protection" alors j'utilise un truc du genre ...
(qui au passage à plus de réussite que les tiennes !!!!)

procedure Test4(C1, C2, C3: TClasseDouteuseClass);
var
O1, O2, O3: TClasseDouteuse;
begin
O1 := C1.Create;
try
O1.DoSomething;
O2 := C2.Create;
try
O2.DoSomething;
O3 := C3.Create;
try
O3.DoSomething;
finally
O3.Free;
end;
finally
O2.Free;
end;
finally
O1.Free;
end;
end;

38 victoires sur 76 tests effectués
c'est à dire 50,0 % de réussite

Mais il est clair que ta 2ème méthode est bien plus simple d'utilisation...

Question:
Ne devrait on pas, normalement, créer les objets en dehors du bloc Try..Finally qui les libères ?
Ok chez toi ils sont initialisés à Nil grâce à AllNil ce qui modifie les données :)

Bon j'ai pas pris le temps d'examiner les logs pour voir ou se situent les différences

Mais Delphi m'informe de ceci :

//*****************************************************************************
Pour la Méthode N°2
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

1 - 12 bytes: TClasseMembreBugge x 7, TClasseCompletementBuggee x 31, TClasseDestructeurBugge x 31, TClasseDouteuse x 3

---------------------------
OK
---------------------------

//*****************************************************************************
Pour la Méthode N°3
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

1 - 12 bytes: TClasseCompletementBuggee x 31, TClasseDestructeurBugge x 31

---------------------------
OK
---------------------------

//*****************************************************************************
La mienne
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

1 - 12 bytes: TClasseCompletementBuggee x 24, TClasseDestructeurBugge x 24

---------------------------
OK
---------------------------


Il semblerait donc qu'elle ne soit pas si performante que tu le pensait ;-)
Qu'en penses-tu ? :)

@+
Cirec
Albedo039 Messages postés 18 Date d'inscription mercredi 8 novembre 2006 Statut Membre Dernière intervention 31 janvier 2008
14 juin 2007 à 15:18
Ze class, la demo ;)
Merci Cirec.
Pour D9 <> D10, c'est une erreur d'inattention. Et comme je n'ai plus D9 j'ai pas vérifié.

Pour ExplicitHeight, il revient toujours le bougre ! Donc il suffit de faire Ignorer et tout compile (du moins testé sous D6).

Mais sinon, dites moi, comment faites vos pour détruire les objets ? méthode 1, 2 ou 3 de la démo ? Personellement j'étais encore à la méthode 1 y'a pas si longtemps, maintenant, c'est la méthode 2 que j'utilise (plus court, et fonctionne à 100%).

++
Utilisateur anonyme
14 juin 2007 à 13:06
Salut,
Chouette démo ... comme toujours

une petite erreur qui empêche la compilation sous D9 (Delphi 2005) :

procedure TFrmTest.FormCreate(Sender: TObject);
begin
{$IFDEF DELPHI_9}
ReportMemoryLeaksOnShutdown := True;
{$ENDIF}
end;

Devrait en fait être :

procedure TFrmTest.FormCreate(Sender: TObject);
begin
{$IFDEF DELPHI_10}
ReportMemoryLeaksOnShutdown := True;
{$ENDIF}
end;


ReportMemoryLeaksOnShutdown n'est disponible que depuis D10

Il faut aussi, dans le DFM, supprimer ceci:
ExplicitHeight = 307 // D10 Uniquement
de l'Object TMemo (MemoLog)
Salut,
Merci pour ton appréciation !

T'en as des idées toi de surcharger des méthodes dans les dll ! C'est une façon de faire des plugins pour ton application ?
Je vais de ce pas me pencher sur le problème...
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
14 juin 2007 à 12:20
Bonne idée de code!

Maintenant, je voudrais la même chose, mais avec des DLL en plus :-)
Je n'ai pas encore réussi à comprendre pourquoi certains appels de méthodes virtuelle d'une classe (depuis l'exe) plantent quand la méthode a été overloadée dans la DLL, et encore pas toujours (c'est en fait ça mon problème: pourquoi ça ne plante par systématiquement!?)... Peut-être que ça vient de la VMT qui n'est pas partagée entre la DLL et l'EXE, mais alors pourquoi ça marche avec les packages? Est-ce que ça voudrait dire que dans le code de LoadPackage il y a un partage de VMT?

Si quelqu'un a une idée...
J'ai pas précisé mais pour utiliser le programme de test, il faut l'executer hors Delphi, sinon vous allez fatigue contre mulot à faire "continuer" à chaque exception levée !
Donc "Projet > Exécuter sans déboguer" est la meilleure solution
Rejoignez-nous