AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Speicherproblem mit Objekten in DLL
Thema durchsuchen
Ansicht
Themen-Optionen

Speicherproblem mit Objekten in DLL

Ein Thema von BastiFantasti · begonnen am 4. Dez 2023 · letzter Beitrag vom 8. Dez 2023
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.002 Beiträge
 
Delphi 12 Athens
 
#1

AW: Speicherproblem mit Objekten in DLL

  Alt 5. Dez 2023, 07:44
Die entscheidende Frage ist doch:
Wird der Destruktor in der DLL durchlaufen, sprich kommst du an einem Haltepunkt darin an?

Wenn Hostanwendung und DLL in der gleichen Projektgruppe liegen, solltest du direkt in der DLL debuggen können, sofern Debuginformationen und ggf. externe Debugsymbole aktiviert sind. Ansonsten kannst du die Hostanwendung auch als solche im DLL-Projekt eintragen und dieses dann starten.

Wichtig ist dabei, dass Speicher nicht unbedingt sofort wieder freigegeben wird. Zur Optimierung behält der Speichermanager den Speicher ggf. auch, um ihn später erneut zu verwenden. Deshalb kann man am Speicherverbrauch nicht unmittelbar sehen, ob der Speicher freigegeben wird.

In den Beispielen zu FastMM4 z.B. ist ein Beispiel enthalten, wie man die Speicherbelegung direkt sehen kann. Außerdem zeigt es Speicherlecks beim Beenden an. Das funktioniert in einfacher Form auch mit ReportMemoryLeaksOnShutdown, das in Delphi bereits integriert ist.

Bezüglich des Records:
Ich persönlich würde die Klasse in der DLL (oder eine zusätzliche Verwaltungsklasse) einfach mit Implementierung eines Interfaces implementieren, das dann von der Hostanwendung abgerufen werden kann. Dann kann man die Klasse dort direkt nutzen.
Dafür kannst du z.B. mein AppCentral Projekt nutzen:
https://www.delphipraxis.net/213199-...ng-dlls-c.html
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
BastiFantasti

Registriert seit: 5. Nov 2014
Ort: Baden Württemberg
136 Beiträge
 
Delphi 12 Athens
 
#2

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 08:16
Die DLL wird zu dem Zeitpunkt nicht beendet.
D.h. der Destruktor wird auch noch nicht durchlaufen.
Die DLL läuft in der Anwendung über mehrere Tage/Wochen.

FastMM4 habe ich in die DLL eingehängt und bekomme beim Beendern aber nur ein Speicherleck von ein paar kB.
Das Problem ist aber, dass obwohl das Objekt zur Laufzeit instanziert und Freigegeben wird, die DLL den Speicher immer aufaddiert und nichts mehr davon freigibt.
D.h. nach ein paar Iterationen belegt die DLL ihre vollen 2GB Speicher.

Wie gesagt funktionieren die gleichen Aufrufe zum Erstellen und Freigeben des Objekts in einer Testanbwendung wie erwartet.
Bastian
  Mit Zitat antworten Zitat
TiGü

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

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 09:28
Fang mal von vorne an und mache dir ein ganz kleines Konsolenprogramm (kein VCL!) und rufe von dort die exportierte DLL-Funktion auf.
  Mit Zitat antworten Zitat
BastiFantasti

Registriert seit: 5. Nov 2014
Ort: Baden Württemberg
136 Beiträge
 
Delphi 12 Athens
 
#4

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 09:41
Ja ich glaube da werde ich nicht drum rum kommen...
Ich werde berichten
Bastian
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
725 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 12:08
Du übergibst der Dll Funktion den String? Um Spass mit langen Strings zu vermeiden verwende ich für die Kommunikation mit Dll's Named Pipes oder gleich einen Netzwerk Socket.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
BastiFantasti

Registriert seit: 5. Nov 2014
Ort: Baden Württemberg
136 Beiträge
 
Delphi 12 Athens
 
#6

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 14:06
Du übergibst der Dll Funktion den String? Um Spass mit langen Strings zu vermeiden verwende ich für die Kommunikation mit Dll's Named Pipes oder gleich einen Netzwerk Socket.
Der Übergabeparameter an die DLL ist nur ein Record in dieser Form:


Code:
  RFTPEventStr = Record

    // event info
    Event: Longword; // event code
    SubEvent: Longword; // sub-event code

    // user info
    SessionID: Longword; // unique ID of the FTP session
    User: array [0 .. 39] of AnsiChar; // user name
    ClientIP: array [0 .. 15] of AnsiChar; // IP number of client
    LocalIP: array [0 .. 15] of AnsiChar; // IP number the client connected to

    // event attributes
    Duration: Longword; // duration of events (in seconds)
    Size: Longword; // size of object (i.e. file)

    // hook info
    hWindow: word; // window handle to post decision to
    Message: longint; // message to post
    pReplyText: PAnsiChar; // pointer to text to send to user
    AuxOne: array [0 .. 511] of AnsiChar; // auxiliary area one
    AuxTwo: array [0 .. 511] of AnsiChar; // auxiliary area two

  end;
Das ist soweit aber iO. Die Daten aus dem Objekt werden nur innerhalb der DLL verwendet, also nicht an die Hostanwendung durchgereicht.
Bastian
  Mit Zitat antworten Zitat
BastiFantasti

Registriert seit: 5. Nov 2014
Ort: Baden Württemberg
136 Beiträge
 
Delphi 12 Athens
 
#7

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 14:27
Hier mal noch ein Bild von dem Problem im Anhang.

Ich verwende die ganzen TJsonArray, TJSonPair usw alle nur indirekt.

Ich erzeuge mir mein Delphiobjekt über die integrierten Funktionen:

Code:
result := TJson.JsonToObject<TMyObject>(js);
js ist der String mit dem nach JSON serialisierten Delphi Objekt.

Die Funktion TJson.JsonToObject ist aus der REST.Json unit
Angehängte Grafiken
Dateityp: png massive_memoryleak.png (31,8 KB, 15x aufgerufen)
Bastian
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.002 Beiträge
 
Delphi 12 Athens
 
#8

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 12:12
Die DLL wird zu dem Zeitpunkt nicht beendet.
D.h. der Destruktor wird auch noch nicht durchlaufen.
Wenn kein Destruktor durchlaufen wird, wird auch nichts freigegeben. Du hast eingangs doch aber genau das beschrieben:
Wenn ich nun die gleiche Klasse in eine Win32 dll verfrachte und das Objekt dort instanziere und wieder freigebe, steigt der Speicherverbrauch bei jedem Aufruf aufs neue an. D.h. mit jedem neuen Durchlauf des Konstruktors schnappt sich die Anwendung zusätzliche 2-5MB.
Darum kann ich dir nicht mehr folgen, wenn du plötzlich sagst, dass gar kein Destruktor durchlaufen wird. Wo wird denn nun Speicher reserviert und wo soll er freigegeben werden? Egal, ob da nun ein Destruktor involviert ist oder du manuell FreeMem aufrufst, kannst du doch dort einen Haltepunkt setzen, um zu prüfen, ob die Freigabe durchgeführt wird.

Du übergibst der Dll Funktion den String? Um Spass mit langen Strings zu vermeiden verwende ich für die Kommunikation mit Dll's Named Pipes oder gleich einen Netzwerk Socket.
Wozu der Aufwand? WideStrings können z.B. Strings mit bis zu ca. 2^30 Zeichen enthalten. Und wenn du dann noch ein Interface verwendest, hast du eine schöne Schnittstelle.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
BastiFantasti

Registriert seit: 5. Nov 2014
Ort: Baden Württemberg
136 Beiträge
 
Delphi 12 Athens
 
#9

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 14:02
Oh, das war ein Missverständnis.
Der Destruktor der Klasse, der das Objekt freigibt wird natürlich durchlaufen.
Nur die DLL wird nicht freigegeben (kein PROCESS_DETACH)

Also Objekt auf (create) - verwenden - Objekt zu (freeandnil)
Der Klassendestruktor wird auch durchlaufen und die enthaltenen TList Objekte werden korrekt freigegeben.

Ich habe jetzt noch etwas weiter recherchiert und habe gesehen, dass es mit der Objektdeserialisierung zusammenhängen muss.
FastMM4 zeigt mir unzählige Elemente an die noch offen sind, wenn die Anwendung beendet wird (obwohl die Objekte freigegeben sind).

Erschwerend kommt hinzu, dass diese Aufrufe innerhalb eines TThreads erfolgen. Eventuell gibt es auch hier Probleme mit der Speicherverwaltung / Freigabe.

Ich habe eine Test DLL gebaut, wo nur eine Funktion exportiert wird, die genau die gleiche Funktionalität abbildet wie oben beschrieben (Objekt auf, verwenden, zu)

Da tritt dieses Speicherleck nicht auf.
Bastian
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
725 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: Speicherproblem mit Objekten in DLL

  Alt 6. Dez 2023, 15:40
Das leakt auch wenn nur in der Exe aufgerufen? Wenn nicht, würde mich wundern wenn ein anderes Verhalten für Dll implementiert worden wäre. (wie auch immer das gehen sollte)

Du übergibst der Dll Funktion den String? Um Spass mit langen Strings zu vermeiden verwende ich für die Kommunikation mit Dll's Named Pipes oder gleich einen Netzwerk Socket.
Wozu der Aufwand? WideStrings können z.B. Strings mit bis zu ca. 2^30 Zeichen enthalten. Und wenn du dann noch ein Interface verwendest, hast du eine schöne Schnittstelle.
Ja, das musst Du schon beantworten. Wozu soll ich mir den Aufwand machen und mich mit Interfaces belasten?
Ich kann mit einem Modul alle beliebigen Daten übertragen die ich will. Eine serialisierbare Memtable kümmert sich intern um alles nötige zur Datenverwaltung. Einmal eingebunden kann ich mit allen Modulen kommunizieren. Egal ob auf einem Rechner, zwischen Diensten, zwischen Rechnern, übers Internet. Selbst broadcast.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.

Geändert von Sinspin ( 6. Dez 2023 um 15:42 Uhr)
  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 13:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz