AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Fehler beim Programm beenden
Thema durchsuchen
Ansicht
Themen-Optionen

Fehler beim Programm beenden

Ein Thema von Jens Hartmann · begonnen am 19. Okt 2015 · letzter Beitrag vom 15. Nov 2015
Antwort Antwort
Seite 2 von 4     12 34      
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#11

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 08:38
Ach so, eins noch. Kann man die vielen Memoryleaks irgendwie den Variablen zuordnen? Weil außer die drei Objekte TOCustomer, TOBuilding, TOSystem sind diese ja nicht eindeutig.
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 08:42
Wie geht man einen Sack voll Memleaks an?

Man beseitigt die bei den bekannten Typen und fängt mit dem an, der die meisten Leaks hat. Diese UnicodeString Leaks sind idR nur Folgefehler davon
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.388 Beiträge
 
Delphi 12 Athens
 
#13

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 09:16
Hallöle...
Zitat:
Ach so, eins noch. Kann man die vielen Memoryleaks irgendwie den Variablen zuordnen?
Viel wichtiger ist es das ReportMemoryLeaks grundsätzlich im Debug Mode an zu haben. Da sieht man sofort an welcher Ecke man das gerade eingebaut hat und muß nicht ein halbes Jahr später rätseln... In der Regel sieht man sofort den Knackpunkt weil man gedanklich an der Stelle drinsteckt.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 09:56
Warum schlägt keiner vor den vollständigen FastMM4 zu installieren und anhand der viel ausführlicheren Fehlermeldungen das Problem einzukreisen?

Tutorials:
http://wiert.me/2009/07/29/delphi-fa...-introduction/
http://delphibistro.com/?p=186
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#15

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 12:11
Vielleicht nicht schön, aber MemoryLeaks beim Beenden sind eh egal. Wenn ich das Haus eh abbrenne, brauch eich die Küche vorher auch nicht feucht wischen. Ich hätte allerdings das Bestreben es ohne MemoryLeaks zu schaffen. Zumindest bei denen für die ich selbst verantwortlich bin.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#16

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 13:42
Wer sagt denn, daß die Leaks nicht schon längst im Lauf des Programms autreten? ODer kann das der FastMM so genau lokalisieren, wann man vergessen hat den Speicher freizugeben ?

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#17

AW: Fehler beim Programm beenden

  Alt 20. Okt 2015, 17:23
Zu VST und Memory Leaks fallen mir als allererstes immer drei Sachen ein:
  1. VST.NodeDataSize initialisiert?
  2. OnFreeNode Event implementiert und deinen Record darin auch ordentlich finalisiert Finalize(NodeData^) ?
  3. Eine kleine Eigenheit vom VST, durch welche OnFreeNode nur dann aufgerufen wird, wenn die Node vorher validated war. Validated wird eine Node nachdem sie zum ersten Mal tatsächlich sichtbar war oder nach manuellem Aufruf von VST.ValidateNode .
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#18

AW: Fehler beim Programm beenden

  Alt 22. Okt 2015, 21:51
Hallo zusammen,

so, die Fehlermeldung beim Programm beenden scheint erstmal weg zu sein. Allerdings sind die MemoryLeaks noch vorhanden. Ich habe jetzt den Tip von "Zacherl" befolgt und das Event "OnFreeNode" entsprechend eingebaut. Irgendwie glaube ich allerdings, dass das ganze nicht ganz sauber Programmiert ist. Ich möchte Euch gerne daher mal versuchen die jeweiligen Teilabschnitte aufzuführen und wäre Euch dankbar, wenn Ihr mir ein kurzes Feedback geben könntet.

So, ich versuch das mal Schrittweise darzustellen. Ich erzeuge ein VST mit ungefähr folgendem Aufbau:
Code:
+Hauptknoden (Zeigt den Datenbankpfad an)
   +Kunde_1
     +Objekt_1
       +System_1
         +Menü_1
         +Menü_2
         +Menü_3
       +System_2
         +Menü_1
         +Menü_2
         +Menü_3
     +Objekt_2
       +System_1
         +Menü_1
         +Menü_2
         +Menü_3
   +Kunde_2
     +Objekt_1
       +System_1
         +Menü_1
         +Menü_2
         +Menü_3
     +Objekt_2
       +System_1
         +Menü_1
         +Menü_2
         +Menü_3
Jeder Kunde kann mehrere Objekte haben. Jedes Objekt kann mehrere Systeme haben und Jedes System hat mehrere Menüpunkte.

Erzeugen tue ich das ganze dann in etwa so...

Ich habe je ein Objekt für die Kundendaten, Objektdaten und Systemdaten. Diese sind jeweils ähnlich und wie folgt aufgebaut...

Delphi-Quellcode:
unit Customers;

interface

uses
  Buildings;

{ TObject für die Kundendaten }
type
  TOCustomers = class(TObject)
    private
      FID : integer; //ID
      FESID : integer; //ESID
      FName : string; //Name des Kunden
      FOrt : string; //Ort des Kunden
      FStraße : string; //Straße des Kunden
      FAnsprechpartnerId : integer; //Ansprechpartnernummer
      FAnsprechpartner : string; //Ansprechpartner
      FAnsPosition : string; //Position/Stellung
      FEMail : string; //EMail des Ansprechpartners
      FTel1 : string; //Telefonnummer 1 des Ansprechpartners
      FTel2 : string; //Telefonnummer 2 des Ansprechpartners
      FFax : string; //Faxnummer des Ansprechpartners
      FBemerkung : string; //Kunden Zusatzinformation
    public
      property Kunden_Kundennummer : integer read FID write FID;
      property Kunden_ESKundennummer : integer read FESID write FESID;
      property Kunden_Kundenname : string read FName write FName;
      property Kunden_Ort : string read FOrt write FOrt;
      property Kunden_Straße : string read FStraße write FStraße;
      property Kunden_Bemerkung : string read FBemerkung write FBemerkung;
      property Ansprechpartner_Id : integer read FAnsprechpartnerId write FAnsprechpartnerId;
      property Ansprechpartner_Name : string read FAnsprechpartner write FAnsprechpartner;
      property Ansprechpartner_Position : string read FAnsPosition write FAnsPosition;
      property Ansprechpartner_EMail : string read FEMail write FEMail;
      property Ansprechpartner_Telefon1 : string read FTel1 write FTel1;
      property Ansprechpartner_Telefon2 : string read FTel2 write FTel2;
      property Ansprechpartner_Fax : string read FFax write FFax;
  end;

implementation

end.
ähnlich sieht das Objekt für "Objekte" und "System" aus.

In meinem Hauptformular nutze ich die Objekte wie folgt:

Delphi-Quellcode:
...
interface

uses
...

  type
    PCustomersData = ^TCustomersData;
    TCustomersData = record
      FCustomer_Object : TObject;
    end;

  type
    PBuildingsData = ^TBuildingsData;
    TBuildingsData = record
      FBuilding_Object : TObject;
    end;

  type
    PSystemsData = ^TSystemsData;
    TSystemsData = record
      FSystem_Object : TObject;
    end;

...

  private
    { Private-Deklarationen }
    var

    ....
    //Diese Globalen Variablen nutze ich für das LoadData
    TMyKunden_Daten : TOCustomers;
    TMyObjekt_Daten : TOBuilding;
    TMySystem_Daten : TOSystems;

...
  public
    { Public-Deklarationen }
    procedure LoadData;
var
  fMyForm: TfMyForm;

implementation

//Das hinzufügen der Daten mache ich dann über folgende Methode:

procedure TfMyForm.LoadData;
var
  I,J,K : Integer;
  CustomerNode, BuildingNode, SystemNode : PVirtualNode;
begin
 try
    vstKunden.BeginUpdate;
    vstKunden.Clear;

    CustomerNode := vstKunden.AddChild(nil);
    vstKunden.InvalidateNode (CustomerNode);
    vstKunden.NodeDataSize:=SizeOf(TCustomersData);
    {Hier glaube ich liegt das erste Problem. Ich setze NodeDataSize auf TCustomersData.
    Was aber ist mit TBuildingData und TSystemData? Benötige ich die nicht,
     weil es nur um den ersten Node geht?}



    //Jetzt lade ich die Kundendaten aus der DB und lasse das ganze durch eine for-Schleife laufen

              TMyKunden_Daten := TOCustomers.Create;
              with TMyKunden_Daten do
                begin
                  //Daten zufügen
    
              //Inerhalb der Schleife folgen dann die tieferen Datenpunkte
              BuildingNode := AddVSTCustomer(vstKunden,CustomerNode,TMyKunden_Daten);

              //Objektedaten laden aus Objektdatenbank
              //Systemdaten
              //Menüpunkte

      end;
    vstKunden.EndUpdate;
    ExpandedRootNodes(vstKunden);
    vstKunden.SortTree(0, sdAscending, True);
 finally
   //Queries schließen etc.
 end;
Delphi-Quellcode:
//Hier die Funktion AddVSTCustomer, die weiteren Add-Funktionen sind ähnlich
  function TfReportClient.AddVSTCustomer(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
    AObject: TObject): PVirtualNode;
  var
    Data : PCustomersData;
  begin
    Result := AVST.AddChild(ANode);
    AVST.ValidateNode(Result,False);
    Data := AVST.GetNodeData(Result);
    Data^.FCustomer_Object := AObject;
  end;
Dann weiße ich über "OnGetText" die Bezeichnung zu und über "OnGetImageIndex" noch ein paar Icons

Das "OnFreeNode" sieht aktuell wie folgt aus...

Delphi-Quellcode:
procedure TfReportClient.vstKundenFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  Kunden_Daten : PCustomersData;
  Objekt_Daten : PBuildingsData;
  System_Daten : PSystemsData;
begin
  case vstKunden.GetNodeLevel(Node) of
    0:
    begin
      Kunden_Daten := Sender.GetNodeData(Node);
      Finalize (Kunden_Daten^);
    end;
    1:
    begin
      Objekt_Daten := Sender.GetNodeData(Node);
      Finalize (Objekt_Daten^);
    end;
    2:
    begin
      System_Daten := Sender.GetNodeData(Node);
      Finalize (System_Daten^);
    end;
  end;
end;
Die Globalen Var. gebe ich im FormDestroy wieder frei...
Delphi-Quellcode:
procedure TfReportClient.FormDestroy(Sender: TObject);
begin
  TMyKunden_Daten.Free;
  TMyObjekt_Daten.Free;
  TMySystem_Daten.Free;
end;
Ich vermute, das einige von Euch jetzt schon die Hände über dem Kopf zusammengeschlagen haben

Aber vieleicht könnt Ihr mir ja mal ein paar Tips geben.

Danke schon mal und Gruß Jens
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#19

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 10:30
//Jetzt lade ich die Kundendaten aus der DB und lasse das ganze durch eine for-Schleife laufen
Dir ist schon bewusst, das du an dieser Stelle immer wieder ein neues Objekt erzeugst, aber nur die letzte Instanz davon im FormDestroy freigibst?

Beispiel: Wenn du 10 Kunden erzeugst TMyKunden_Daten := TOCustomers.Create; , gibst du im FormDestroy nur Nummer 9 frei.
Die Kunden 0 bis 8 hängen noch im Speicher rum und das sind deine Speicherlecks.

Verwalte doch diese Instanzen von Kunden, Systemen und Gebäuden in seperaten Objektlisten.
Bei Freigabe der Objektlisten werden dann auch die darin gespeicherten Instanzen freigeben.

Beispiel:
Delphi-Quellcode:
var
  I, J, K: Integer;
  CustomerNode, BuildingNode, SystemNode: PVirtualNode;
  LCustomer: TOCustomers;
begin
  VstKunden.BeginUpdate;
  try
    VstKunden.Clear;

    CustomerNode := VstKunden.AddChild(nil);
    VstKunden.InvalidateNode(CustomerNode);
    VstKunden.NodeDataSize := SizeOf(TCustomersData);
    { Hier glaube ich liegt das erste Problem. Ich setze NodeDataSize auf TCustomersData.
      Was aber ist mit TBuildingData und TSystemData? Benötige ich die nicht,
      weil es nur um den ersten Node geht? }


    FCustomers := TObjectList.Create;
    // Jetzt lade ich die Kundendaten aus der DB und lasse das ganze durch eine for-Schleife laufen
    for I := 0 to 10 do
    begin
      LCustomer := TOCustomers.Create;
      FCustomers.Add(LCustomer);

      LCustomer.Kunden_Kundenname := 'Hallo';
      LCustomer.Ansprechpartner_Position := 'Hallo';
      LCustomer.Ansprechpartner_Telefon1 := 'Hallo';

      // Inerhalb der Schleife folgen dann die tieferen Datenpunkte
      BuildingNode := AddVSTCustomer(VstKunden, CustomerNode, LCustomer);

      // Objektedaten laden aus Objektdatenbank
      // Systemdaten
      // Menüpunkte
    end;

    // ExpandedRootNodes(VstKunden);
    VstKunden.SortTree(0, SdAscending, True);
  finally
    VstKunden.EndUpdate;
  end;
end;
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
703 Beiträge
 
Delphi 12 Athens
 
#20

AW: Fehler beim Programm beenden

  Alt 23. Okt 2015, 10:40
Ergänzung:

Das OnFreeNode des VST brauchst du dann nicht mehr, da du die Freigabe selbst machst.

Ist doch auch irgendwie logischer: Du erzeugst die Objekte, übergibst sie dem VST zur Anzeige, und zerstörst sie selbst wieder.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34      


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 17:48 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