Thema: Delphi hängende Interfaces

Einzelnen Beitrag anzeigen

Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.337 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: hängende Interfaces

  Alt 1. Mär 2017, 22:38
Ich will das Thema nochmal aufgreifen...

Weak Referenzen kann ich mit XE3 nicht nutzen. Das Arbeiten mit Pointern finde ich auch nicht optimal.

DUnit und LeakCheck kann ich nicht wirklich nachvollziehen.


Ich habe daher mal ein kleines Projekt gebastelt, um einen Ansatz zu suchen.
Dafür habe ich ein Basisinterface ICleanUp und eine Basisklasse TCleanUp erstellt, die mögliche gegenseitige Referenzen abbauen können.

Man muss allerdings für alle betroffenen Interfaces/Objekte CleanUp(MyIntf) aufrufen.

Ich hänge das Projekt an (XE3, nur Quelle, ohne EurekaLog-Aktivierung).
Hier auch ein Video dazu: https://youtu.be/2yjGr2CoT5E

Mich würde mal Eure Meinung dazu interessieren sowie natürlich auch bessere Lösungen.

In dem Zusammenhang hatte ich überlegt, dass man (bzw. Emba) doch evtl. loggen könnte, welche Referenzen erzeugt und nicht wieder freigegeben werden. Man müsste dazu in _AddRef und _Release m.E. die Speicherstelle der Variable, die Speicherstelle des Objektes und die Quelltextstelle in einer Liste sammeln bzw. wieder löschen.
Einträge, die zum Schluss übrig bleiben, wurden nicht freigegeben.

Ich versuche mal, das zu skizzieren (A und B sind Interfaces, die sich gegenseitig referenzieren können, die Nr am Anfang ist eine Programmzeile):

begin
...
10: A1 := TA.Create
-> Eintrag: Adr(A1) $12345 / Adr(ObjektA1) $456789 / Zeile 10
11: B1 := TB.Create
-> Eintrag: Adr(B1) $12346 / Adr(ObjektB1) $45678A / Zeile 11
...
18: A1.B := B1
-> Eintrag: Adr(A1.fB) $23456 / Adr(ObjektB1) $45678A / Zeile 18
19: B1.A := A1
-> Eintrag: Adr(B1.fA) $23457 / Adr(ObjektA1) $456789 / Zeile 19
...
end
-> löschen: Adr(A1) $12345 / Adr(ObjektA1) $456789 / Zeile 10
-> löschen: Adr(B1) $12346 / Adr(ObjektB1) $45678A / Zeile 11

Also direkt in _AddRef und _Release müsste sowohl die Speicherstelle des zu referenzierenden Objektes bekannt sein als auch die Speicherstelle der Variablen. Dann könnten dort die skizzierten Einträge erzeugt werden und bei Vorliegen von Debug-Infos auch Bezüge zum Quelltext.

Im Beispiel werden beim Prozeduraussprung die Referenzen auf ObjektA1 und ObjektB1 ja je einmal verringert.
Der Debugger weiß ja auch, dass die Variablen A1 und B1 aus dem Scope fallen. Also könnte er erkennen, dass die ersten beiden Einträge obsolet sind und könnte diese löschen oder kennzeichnen.

Somit würden zum Programmende folgende zwei Einträge übrig bleiben:
Adr(A1.fB) $23456 / Adr(ObjektB1) $45678A / Zeile 18
Adr(B1.fA) $23457 / Adr(ObjektA1) $456789 / Zeile 19

Damit könnte man die nicht aufgelösten Referenzen sehr zuverlässig und komfortabel finden.
Emba müsste dazu entsprechende Logs in _AddRef und _Release ermöglichen.

Ist das so denkbar oder ist das in der Form unmöglich?



Ein Reference Tracing bietet übrigens AQTime Pro inzwischen an.
https://www.youtube.com/watch?v=y4qbNwuk2Qs
Man muss jedoch EurekaLog dazu ggf. im Projekt deaktivieren.
Also kann man mit EurekaLog hängende Referenzen finden, dieses dann ausschalten und die Ursache mit AQTime näher untersuchen.
Ich muss allerdings sagen, dass ich das auch nicht so sehr übersichtlich finde.
Angehängte Dateien
Dateityp: zip HangingReferences.zip (123,3 KB, 2x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat