![]() |
[Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Dependency Injection mit dem Spring4Delphi-Framework leistet bei mir seit einiger Zeit gute Dienste. Bislang habe ich das ausschließlich mit nicht-visuellen Klassen praktiziert.
Nun möchte ich das Konzept auf DataModules erweitern:
Delphi-Quellcode:
Mit diesem Gerüst klappt auch alles sehr schön und ich kann das Datenmodul über den DI-Container benutzen. Es wird der Default-Konstruktor und auch der Default-Destruktor durchlaufen.type IdcWallpaper = interface ['{E0D26B15-55CE-400A-9DD5-6EA5A999B375}'] procedure CreateControl(aStartScreen : IdcStartScreen; aParent : TWinControl); end; TdmWallpaper = class(TDataModule, IdcWallpaper) private // IdcWallpaper procedure CreateControl(aStartScreen : IdcStartScreen; aParent : TWinControl); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; implementation {$R *.dfm} uses Spring.Container, Spring.Services; <..> initialization GlobalContainer.RegisterComponent<TdmWallpaper>.Implements<IdcWallpaper>.AsSingleton.DelegateTo( function: TdmWallpaper begin Result := TdmWallpaper.Create(nil); end ) Leider bekomme ich trotzdem eine MemoryLeak-Meldung (leaks are: 13-20 bytes dcWallpaper$43200$ActRec x 1) ![]() Hat jemand dazu eine Idee, wie ich dieses MemoryLeak vermeide? Edit: Wenn ich das Interface in einem separaten TInterfacedObject implementiere und dort das TDataModule verwalte, gibt es keine Probleme, weil dann auch kein DelegateTo mehr nötig ist. |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Die Ursache liegt irgendwo im Compiler - genau das gleiche Problem hatten wir auch in Spring selber
![]() Wahrscheinliche Lösung (ungetestet):
Delphi-Quellcode:
procedure RegisterWallpaper;
begin GlobalContainer.RegisterComponent<TdmWallpaper>.Implements<IdcWallpaper>.AsSingleton.DelegateTo( function: TdmWallpaper begin Result := TdmWallpaper.Create(nil); end ) end; initialization RegisterWallpaper(); Edit: Hab den ![]() |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Vielen Dank für Deinen Tipp. Leider bringt Dein Vorschlag keine Besserung, obwohl ich ihn gern übernommen hätte. Meine Lösung mit einem Wrapper-Objekt erzeugt nicht gerade Clean Code, funktioniert dafür aber.
Dein Link enthält im Kommentar die Erklärung: Alle Variablen, die in einem Initialisierungsteil erzeugt werden, sind global. Damit fallen sie auch aus dem Scope, den der DI-Container verwalten kann und erzeugen beim Shutdown MemoryLeaks. Nun werden ja auf einem Datenmodul einige Komponenten abgelegt. Diese sind dann auch von o.g. Phänomen betroffen, da sie im Create() erzeugt werden. BTW, ich werde mir meine Erklärung in den Info-Header meiner Units schreiben, damit ich beim nächsten Refactoring nicht flasch optimiere ;) |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Zitat:
Das hat imho überhaupt nichts mit der Verwaltung des vom DI Container erzeugten Objekts zu tun. |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Das klingt schon überzeugend...noch überzeugender ist nur, dass die vorgeschlagene Änderung mit der Auslagerung in eine Prozedur leider keinen Effekt zeigte.
Diese anonyme Methode ist ja nur nötig, damit der Default-Konstruktor des DatenModuls aufgerufen wird. Möglicherweise passiert dabei noch etwas mehr. Nehme ich nun mein ungeliebtes Wrapper-Object, so verwaltet der DI-Vontainer das Objekt wie gehabt und richtig und innheralb dessen habe ich die volle Kontrolle über das Erzeugen und Freigeben des Datenmodules. BTW, in den Spring-Demos wird das DelegateTo auch im initialization-Teil eingesetzt. Allerdings werden da auch keine Datenmodule oder Forms erzeugt. |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Sicher, dass du ein Memleak der anonymen Methode aus dem Eingangspost hast und nicht eins des Datamodules? Dieses ist nämlich von TComponent abgeleitet, welches kein RefCounting hat und dementsprechend auch nicht über das Interface freigegeben wird (außer, du hast das selber dazwischen geschaltet).
|
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Eigentlich schon. Dein Einwand mit TComponent ist auch berechtigt, aber:
- sollte nicht der DI-Container die Lebenszyklen verwalten? - sollte der DI-Container nicht auch Nicht-RefConted-Objekte "können"? - der Default-Destruktor wurde ja durchlaufen. - sollte ein leeres TDatamodule eigentlich keine MemLeaks erzeugen? Wie auch immer: Derzeit und mangels gesicherter Erkenntnisse wrappe ich nicht gerefcountete Objecte mit einem gerefcounteten, schäme mich für mein Denglisch und nutze das Konstrukt weiter mit den Spring-DI-Container und entwickle so immer fein gegen Interfaces, dass N. Hodgess [sic!] seine Freude dran hätte ;) |
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Zitat:
Alles, was du in über Interfaces auf dem Container holst, sollte RefCounting benutzen. Genau das gleiche Problem hatte ich mit meinen Views im PresentationModel ja auch. Dort hab ich allerdings noch ein bisschen "drumrum gepfuscht". Zitat:
Zitat:
Zitat:
Zitat:
|
AW: [Spring-DI] MemoryLeak bei Einsatz von DelegatedConstructor
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:01 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 by Thomas Breitkreuz