web-dev-qa-db-fra.com

Delphi - La recompilation d'une application avec 10.2.1 provoque des fuites de mémoire?

Je viens d'installer Delphi 10.2 Release 1. Lorsque je recompile mes applications et que je les lance, je reçois beaucoup de fuites de mémoire. Je n'ai eu aucune fuite de mémoire avec 10.2 (sans la mise à jour). Je n'ai apporté aucune modification au code non plus.

Pour vérifier, j'ai créé une simple application vierge et mis quelques composants sur le formulaire. Pas de code. A exécuté l'application et a obtenu des fuites de mémoire.  Memory leaks from the sample application

Je voulais souligner ceci (ne serait-ce que comme avertissement avant de procéder à la mise à niveau).

Mes questions:

  1. Est-ce que quelqu'un d'autre a vu ce problème?
  2. Y a-t-il quelque chose que je devrais faire ou que je pourrais faire pour résoudre ce problème?

Remarque: J'ai enregistré un problème sur le portail de qualité, juste au cas où il s'agirait d'un problème réel: https://quality.embarcadero.com/browse/RSP-18774 . Dans ce billet, j'ai également joint l'exemple d'application.

13
Rohit

Après quelques recherches, j'ai découvert que les rappels transmis à TThread.CurrentThread.ForceQueue dans TStyledControl.KillResourceLink ne sont jamais exécutés, car avant qu'un thread puisse les gérer, l'application se termine et le destructeur de classe TThread détruit la liste contenant des rappels non gérés.

J'ai résolu ce problème en ajoutant un appel à CheckSynchronize à la fin de FMX.Forms.DoneApplication, ce qui force l'exécution des rappels, ce qui a résolu l'énorme fuite de mémoire.

Je ne sais pas s'il s'agit du correctif correct du problème, mais cela a résolu le problème des fuites de mémoire signalées.

18
Stefan Glienke

J'ai le même problème en utilisant C++ Builder 10.2.1 dans les applications FMX et VCL.

Si j'active CodeGuard, des fuites de mémoire se produisent à la fermeture de l'application.

J'ai un gestionnaire TThread avec OnTerminate: si je mets un point d'arrêt dans ce gestionnaire, lorsque je ferme le programme, il n'est jamais appelé.

Si je mets CheckSynchronize() dans le destructeur de mon formulaire de demande principal, le problème persiste.

Ma solution était une boucle "horrible" comme celle-ci dans le destructeur de la forme principale:

__fastcall TForm3::~TForm3(void) {
    for(int i = 0; i < 10; i++) {
        Sleep(1);
        CheckSynchronize();
    }
}

Cette solution n'est pas déterministe mais peut être utilisée dans votre application en mode débogage pour éviter les messages d'erreur CodeGuard.

Une autre solution consiste à utiliser la fonction WaitFor() si MyThread est un objet TThread:

MyThread = new MyThreadClass();

et DeleteThisTh() est une méthode de cette classe, nous pouvons attendre le thread terminé à l'intérieur de DeleteThisTh():

void MyThreadClass::DeleteThisTh(void) {
    Terminate();
    WaitFor();
    delete this;
}

Dans l'événement OnTerminate, je peux nettoyer mes objets. Prendre note:

  1. delete this est appelé après OnTerminate;
  2. DeleteThisTh() habite dans le thread principal;
0
Emanuele Coli