AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamische Packages - Forms anzeigen - Leak

Offene Frage von "Bernhard Geyer"
Ein Thema von Sequitar · begonnen am 12. Jan 2016 · letzter Beitrag vom 13. Jan 2016
Antwort Antwort
Seite 1 von 2  1 2      
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#1

Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:25
Ich möchte gerne forms in packages zur Verfügung stellen und diese dynamisch laden.
Jetzt habe ich festgestellt, dass der Speicher nicht mehr freigegeben wird (also auch bei leeren Forms ohne Nutzer-Interaktion oder Komponenten).
Wenn die Form angzeigt wird, werden ca. 300 byte nicht mehr freigegeben (vorausgesetzt, "memoryused" stimmt)

Was dagegen tun?

BPL mit Form:
Delphi-Quellcode:
Unit Gui.LoaderTestform;

{ This is a Test form
  for loader to test for memory leaks }

Interface

  Uses
    Windows,
    Messages,
    SysUtils,
    Variants,
    Classes,
    Graphics,
    Controls,
    Forms,
    Dialogs;

  Type
    TTestform = Class(TForm)
      Private
        { Private declarations }
      Public
        { Public declarations }
    End;

  Var
    Testform: TTestform;

Implementation

{$R *.dfm}

Initialization

   Registerclass(TTestform);

Finalization

   Unregisterclass(TTestform);

End.
Hauptprgramm:
Form anzeigen, nachdem das Package dynamisch geladen wurde:
Delphi-Quellcode:
Function Tplgfrm.Loadform(Parent: Tcomponent; Form: String; Modal: Boolean)
    : Boolean;
  Var
    FormClass: Tformclass;
  Begin
    Result := True;
    Try
      Form := 'T' + Form;
      FormClass := TFormClass(GetClass(Form));
      If FormClass = Nil Then
        Begin
          Raise Exception.Create('The form "' + Form + '" is not available.');
          Result := Not Result;
        End
      Else
        Begin
          With TComponentClass(FormClass).Create(Parent) As TCustomForm Do
            Try
              If Modal Then
                Showmodal
              Else
                Show;
            Finally
              // Free;
            End;
        End;
    Except
      Raise Exception.Create('Form could not be loaded.');
      Result := Not Result;
    End;
  End;
Den leak teste ich über die Differenz zweier Aufrufe folgender Funktion:
Delphi-Quellcode:
  Function MemoryUsed: Cardinal;
  Var
    St: TMemoryManagerState;
    Sb: TSmallBlockTypeState;
  Begin
    GetMemoryManagerState(St);
    Result := St.TotalAllocatedMediumBlockSize +
      St.TotalAllocatedLargeBlockSize;
    For Sb In St.SmallBlockTypeStates Do
      Begin
        Result := Result + Sb.UseableBlockSize * Sb.AllocatedBlockCount;
      End;
  End;

Geändert von Sequitar (12. Jan 2016 um 15:13 Uhr)
  Mit Zitat antworten Zitat
Zoot

Registriert seit: 30. Jan 2006
Ort: Hessen
113 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:28

Result := Not(Result);
Lustig.
nach mehmaligen Aufrufen weiß keiner mehr, was Result nun ist.
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:30
Result wurde am anfang auf false gesetzt.
Wenn die form erfolgreich geladen wird, soll der Rückgabewert ja "true" sein. Die form soll ja meist nur einmal geladen werden (und modal angezeigt).


OK, ich seh grad: Result müsste am Anfang auf True initialisiert werden,um sinn zu machen.


Result := Not(Result);
Lustig.
nach mehmaligen Aufrufen weiß keiner mehr, was Result nun ist.

Geändert von Sequitar (12. Jan 2016 um 14:33 Uhr)
  Mit Zitat antworten Zitat
Zoot

Registriert seit: 30. Jan 2006
Ort: Hessen
113 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:33
Wenn die form erfolgreich geladen wird, soll der Rückgabewert ja "true" sein.
Dann setz Result doch auch auf <true>.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:34
NOT als "Funktion" sieht irgendwie immer krank aus.
NOT ist ein Operator. (die Klammer gehrt nicht zum NOT)


Delphi hält keine Informationen welche Form Komponente oder anderer Speicher im Code eines bestimmten Moduls (EXE, DLL, BPL) erstellt/reserviert wurde und somit kann Delphi auch nichts automatisch freigeben, wenn du ein Modul wieder entlädst.

Fazit: DU mußt dir das merken und es beim Entladen der BPL das dann selber freigeben.
(wichtig vorallem bei Komponenten, die im Betrieb Code aus diesem Modul verwenden)
$2B or not $2B
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:42
NOT als "Funktion" sieht irgendwie immer krank aus.
NOT ist ein Operator. (die Klammer gehrt nicht zum NOT)
Gut. Ist geändert.

Delphi hält keine Informationen welche Form Komponente oder anderer Speicher im Code eines bestimmten Moduls (EXE, DLL, BPL) erstellt/reserviert wurde und somit kann Delphi auch nichts automatisch freigeben, wenn du ein Modul wieder entlädst.

Fazit: DU mußt dir das merken und es beim Entladen der BPL das dann selber freigeben.
(wichtig vorallem bei Komponenten, die im Betrieb Code aus diesem Modul verwenden)
ich dachte die form wäre hiermit automatisch wieder freigegeben/ zerstört (und damit auch die daraufliegenden komponenten):
Delphi-Quellcode:
With TComponentClass(FormClass).Create(Nil) As TCustomForm Do
            Try
              If Modal Then
                Showmodal
              Else
                Show;
            Finally
              Free; //hier?
            End;
Oder muss ich jede einzelne Komponente auf der Form zerstören? (Das Problem tritt ja auch bei einer komplett leeren Form auf)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 14:51
Result wurde am anfang auf false gesetzt.
Wenn die form erfolgreich geladen wird, soll der Rückgabewert ja "true" sein. Die form soll ja meist nur einmal geladen werden (und modal angezeigt).


OK, ich seh grad: Result müsste am Anfang auf True initialisiert werden,um sinn zu machen.


Result := Not(Result);
Lustig.
nach mehmaligen Aufrufen weiß keiner mehr, was Result nun ist.
Das glaube ich jetzt nicht wirklich.

Result := Not(Result) , was theoretisch den Wert Result umkehren könnte, steht immer hinter dem Werfen einer Exception und wird von daher im realen Leben vermutlich nie ausgeführt. (oder hab' ich da was übersehen?)

Dashier verstehe ich nicht:
Delphi-Quellcode:
 With TComponentClass(FormClass).Create(Nil) As TCustomForm Do
            Try
              If Modal Then
                Showmodal
              Else
                Show;
            Finally
              Free;
            End;
Du erstellst ein Formular, dann entscheidest Du, ob es Modal oder nicht angezeigt werden soll.
Bei ShowModal dürfte das auch funktionieren, wenn im Finally das Free aufgerufen wird.

Wie ist das denn beim Show? Bleibt das Programm da quasi im Quelltext stehen und wartet, bis das Formular geschlossen wird, bevor im Finally das Free aufgerufen wird?

Hab's gerade mal unter Delphi 7 ausprobiert: Das auf diese Art und Weise erstellte Formular bekomme ich nicht wirklich zu sehen, ein kurzes Flimmern, bei dem man erahnen kann, dass da irgendwo ein Formular angezeigt werden könnte, ja, aber ein benutztbares Formular? Fehlanzeige.

Automatisch "zerstört" werden könnte es nur, wenn im Create statt Nil ein Parent angegeben wird. Wenn niemand weiß, wem das Formular gehört, wer soll denn dann wissen, wann es "beseitigt" werden soll?

Geändert von nahpets (12. Jan 2016 um 14:52 Uhr) Grund: Schreibfehler, mal wieder :-(
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 15:00
Zitat:
Wie ist das denn beim Show? Bleibt das Programm da quasi im Quelltext stehen und wartet, bis das Formular geschlossen wird, bevor im Finally das Free aufgerufen wird?

Hab's gerade mal unter Delphi 7 ausprobiert: Das auf diese Art und Weise erstellte Formular bekomme ich nicht wirklich zu sehen, ein kurzes Flimmern, bei dem man erahnen kann, dass da irgendwo ein Formular angezeigt werden könnte, ja, aber ein benutztbares Formular? Fehlanzeige.
Das ist mir auch schon aufgefallen, daher habe ich bisher alle Formulare modal erstellt. Wusste nicht wie man das ändert (ausser das formular nicht direkt wieder zu zerstören, was aber auch nichts daran ändert, was nahpets beschreibt: Kurzes Flackern und sonst nichts)


Das Formular könnte theoretisch von unterschiedlichen Anwendungen (oder anderen Formularen) geladen werden. Habe daher jetzt einen "parent" parameter eingefügt, der dann für die Freigabe zuständig sein muss und dem ich als Result die erstellte form zur verfügung stelle:


Delphi-Quellcode:
Function Tplgfrm.Loadform(Parent: Tcomponent; Form: String; Modal: Boolean)
    : TCustomForm;
  Var
    FormClass: Tformclass;
  Begin
    Try
      Form := 'T' + Form;
      FormClass := TFormClass(GetClass(Form));
      If FormClass = Nil Then
        Raise Exception.Create('The form "' + Form + '" is not available.')
      Else
        Begin
          Result := TComponentClass(FormClass).Create(Parent) As TCustomForm;
          With Result Do
            Try
              If Modal Then
                Showmodal
              Else
                Show;
            Finally
              // Free;
            End;
        End;
    Except
      Raise Exception.Create('Form could not be loaded.');
    End;
  End;


//Aufruf

Form := Loadform(Application, 'Formname', True);
Form.Free;

Geändert von Sequitar (12. Jan 2016 um 15:34 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#9

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 15:35
Ich versuchs mal naiv:

Du hast da Deine FormClass.

Wie wäre es, wenn Du die Funktion von diesem Typ machst?

Sowas in der Art:
Delphi-Quellcode:
Function Tplgfrm.Loadform(Parent: Tcomponent; Form: String; Modal: Boolean) : Tformclass;
  Begin
    Try
      Form := 'T' + Form;
      Result := TFormClass(GetClass(Form));
      If not Assigned(Result) Then
        Begin
          Raise Exception.Create('The form "' + Form + '" is not available.');
        End
      Else
        Begin
          With TComponentClass(Result).Create(Parent) As TCustomForm Do
            Try
              If Modal Then
                Showmodal
              Else
                Show;
            Finally
              // Free;
            End;
        End;
    Except
      Raise Exception.Create('Form could not be loaded.');
    End;
  End;
Im Programm wäre dann eventuell sowas möglich:
Delphi-Quellcode:
Procedure irgendwas;
Var
  FormClass : TFormClass;
begin
  FormClass := plgfrm.Loadform(Self,'FromWieAuchImmer', True);

  if Assigned(FormClass) then begin
    ...
    FormClass.Close;
    FormClass.Free;
  end;
end;
Wobei, das Anzeigen des Formulares würd' ich aus der Funktion rausnehmen und im aufrufenden Programm machen, dann kannst Du besser entscheiden, ob das Formular direkt nach dem ShowModal freigegeben wird oder nicht.

Bei 'nem Show kannst Du die Freigabe dann auch beim Beenden des Programmes machen (oder an anderer, sinnvoller Stelle), die variabel FormClass muss dann nur an entsprechender Stelle deklariert werden und nicht innerhalb der Prozedur, die das Formular "anfordert".
  Mit Zitat antworten Zitat
Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Dynamische Packages - Forms anzeigen - Leak

  Alt 12. Jan 2016, 15:45
Übrigens verringert sich das Leak bei Weglassen von Registerclass in der Unit der einzelnen Forms. (Natürlich ist das notwendig um die Klassen zu identifizieren, wenn ich dynamische Packages nutze). Irgendein Workaround / Tip hierfür?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz