![]() |
unverständlicher Memoryleak in Funktion
Moin,
ich verzweifle gerade an einem Memoryleak, bei dem ich nicht verstehe warum er entsteht. Und zwar habe ich folgende Funktion:
Delphi-Quellcode:
Es handelt sich hierbei um eine ganz normale Funktion und keine Class-Function. Deleaker sagt mir jetzt dass in Zeile 5 und in Zeile 8 der Funktion jeweils ein Memoryleak sind (um genau zu sein durch die Objekte TJsonString, TJsonArray und TList<TJsonValue>).
function TxxxManager.StringsToJSONArray(const Data: TStrings): TJSONArray;
var i: Integer; begin Result := TJSONArray.Create; for i := 0 to Data.Count - 1 do begin Result.Add(Data[i]); end; end; Ich rufe diese Funktion aber über folgende Funktion auf:
Delphi-Quellcode:
Was ich jetzt nicht verstehe. Ich gebe mManager wieder frei. Müsste er dann nicht auch die Resultvariable und Abhängigkeiten davon wieder freigeben oder habe ich da gerade ein Verständnisproblem? Bei Klassenfunktionen umgehe ich das Problem indem ich den Result in eine globale Variable kippe, die dann als Result übergebe und über den Klassendesturktor dann die globale Variable (die selbstverständlich private ist) wieder freigebe. Aber bei einer normalen Funktion müsste ich mir diesen Teil doch eigentlich schenken können, da doch bei FreeAndNil auch die Results wieder freigegeben werden. Zumindest hab ich das bisher so verstanden.
function Global.Principals: TJSONArray;
var mManager : TxxxManager; mMandanten : TStringList; begin mManager := TxxxManager.Create; try mMandanten := TMandantRepository.GetMandantenMitKonzern(cKONZERN_XXX); Result := mManager.StringsToJSONArray(mMandanten); finally FreeAndNil(mManager); end; end; Könnte mir da vielleicht jemand weiter helfen? Ich komme ursprünglich aus dem C#-Umfeld und da hatten wir nen Garbage-Collector, der sich um das alles gekümmert hat. Daher fehlen mir hier grad so ein wenig die Basics in der Speicherverwaltung, weil das ein Thema war, welches ich vor Delphi nicht berücksichtigen musste. Vielen Dank schon einmal im Voraus. Viele Grüße Maliko |
AW: unverständlicher Memoryleak in Funktion
Das würde dann funktionieren, wenn TxxxManager.StringsToJSONArray nicht bei jedem Aufruf eine neue Instanz erzeugen würde, sondern eine Property von TxxxManager wäre, die bei jedem Aufruf nur neu befüllt wird. Natürlich muss das dahinterliegende Feld im Destruktor von TxxxManager aber wieder freigegeben werden.
[edit] Alternativ könnte TxxxManager aber auch eine Liste der erzeugten Instanzen pflegen als TObjectList<TJSONArray>. Bei jedem Aufruf von StringsToJSONArray wird das Result dann der Liste hinzugefügt und die Liste im Destruktor wieder freigegeben. Das setzt aber voraus, dass danach nirgends mehr auf so ein Result zugegriffen wird, egal wo. [/edit] |
AW: unverständlicher Memoryleak in Funktion
Da StringsToJSONArray und Principals eine neu erstellte Komponente raus geben, muß dass dann der freigeben, welcher Principals aufgerufen hat.
Wenn da der Manager hier das Result nicht freigibt, gibt es da kein Problem, weil unabhängig. Aber wer gibt mMandanten wieder frei? Oder ist diese Liste z.B. ein Signleton, die intern verwaltet und von der Kompontene später freigegeben wird? |
AW: unverständlicher Memoryleak in Funktion
.. Du erstellst in der ersten Funktion eine Instanz einer Klasse.
Die übergibst Du in der zweiten Funktion dem result der Funktion. Wo die Instanz terminiert wird ist hier nicht ersichtlich. Erstellt wird sie in Funktion 1, daher wird auch dort der Leak gemeldet. Nein result von Funktionen werden beim Beenden der Funktion nicht freigegeben - wo würde das auch hinführen? Grüße Klaus |
AW: unverständlicher Memoryleak in Funktion
Zitat:
Sprich es kann sein, dass dieser Memoryleak eigentlich gar nicht existiert, da der DataSnap-Server sich um das Disposing des Global-Results kümmert? |
AW: unverständlicher Memoryleak in Funktion
Ob DataSnap die Objekte freigibt, welche als Result aus Servermethoden rausgehen, bzw. aus Client-Methoden zurück zum Server, das ist eine Einstellung.
Ich glaub in den automatisch generierten Server-/Client-Klassen gab es eine Variable in der Server-Klasse, welche dieses Free regelt. Per Standard macht DataSnap hier aber das Free, da man als Entwickler keinen Zugriff darauf hat, wann die Übertragung abgeschlossen ist, nachdem die Methode verlassen wurde. |
AW: unverständlicher Memoryleak in Funktion
Da ich da keine Einstellung verändert habe wird sich DataSnap dann wohl darum kümmern. Muss ich gleich mal ausprobieren. Ich starte den Service mal Lokal, setz nen Request ab und beobachte die Arbeitsspeicherveränderung im Task. Wenn sich der Arbeitsspeicher nicht verändert, dann ist es kein Leak.
|
AW: unverständlicher Memoryleak in Funktion
Du kannst ja im Destroy deines Objektes, welches raus geht, die Freigabe debuggen/loggen.
Falls es sich dort nicht Debuggen oder diese Klasse sich nicht ableiten lässt, dann kann man sich auch über den TVirtualMethodInterceptor dranhängen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 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