![]() |
:= NIL ist gleich release?
Hallo!
Ich lese öffter, das es in delphi möglich ist einfach einen Speicher wieder frei zu geben, indem man dem Zeiger auf NIL setzt. Die C-Jungs müssen scheinbar noch manuell den release aufrufen?! Ich rede nicht von .Net wo die Speicher-Abfallbeseitigung das erledigt :lol: Habe ich da etwas verpasst? Oder wie funktioniert das? Frank :coder: |
Re: := NIL ist gleich free?
Also ich war der Meinung das wenn man was = nil setzt, das dann die Variable zwar auf nil zeigt, das eigentliche Objekt doer was auch immer immernoch im Speicher existiert.. :gruebel:
|
Re: := NIL ist gleich free?
Zitat:
|
Re: := NIL ist gleich free?
Das Setzten auf Nil verschlimmbessert die Sache, weil nun die automatische Freigabe durch den Destruktor des Owner auch nicht mehr funktioniert, weil dieser meinet das Objekt sei schon zerstört, da Referenz NIL ist.
|
Re: := NIL ist gleich free?
Zitat:
|
Re: := NIL ist gleich free?
Zitat:
wenn das betreffende Objekt ein Interface implementiert (also z.B. eine Instanz eines COM-Servers ist) dann macht Delphi eine Referenzzählung. Das heisst, daß das Objekt freigegeben wird wenn die letzte Referenz auf NIL gesetzt wird, also von der Wirkung her wie bei dot-net-Objekten. Bei "normalen" Objekten trifft das nicht zu. Diese müssen explizit freigegeben werden. Ciao, Ralf |
Re: := NIL ist gleich free?
Zitat:
Wie funktioniert das? Wer zählt den da mit, wenn ein Pointer auf NIL gesetzt wird? Frank PS. Habe den Titel geändert! |
Re: := NIL ist gleich free?
Zitat:
|
Re: := NIL ist gleich free?
Hallo,
Zitat:
Nochmal zum Verständnis: Jedesmal, wenn eine neue Referenz auf ein Interface erzeugt wird, sorgt Delphi dafür, dass die Methode _AddRef des Interface aufgerufen wird. Beim Entfernen der Referenz (auf nil setzen, Scope verlassen) wird automatisch _Release aufgerufen. Deshalb sind z. B. Funktionen mit einem try..Finally umgeben. Im Finally wird _Release für alle lokalen Referenzen aufgerufen. Da das alles die Compiler-Magic macht, bekommt der Programmierer davon normalerweise nichts mit. Gruß xaromz |
Re: := NIL ist gleich release?
Anmerkung string- und "array of"-Variablen werden genauso behandelt. Der einzige Unterschied ist das nicht die COM-Objekt-Referenzzaehlung sondern die Delphi-eigene Referenzzaehlung fuer diese Typen zum Zuge kommt.
|
Re: := NIL ist gleich release?
OK Verstehe!
Letzte Frage: Ist ein Aufruf von _release schlecht oder schädlich? Frank |
Re: := NIL ist gleich release?
Zitat:
Wenn Sie wie beim IE < 7 fehlerhaft in der internen Referenzzählung ist, dann ist es nicht zu vermeiden selbst _Release aufzurufen um keine riesigen Speicherlücken zu haben. |
Re: := NIL ist gleich release?
Zitat:
|
Re: := NIL ist gleich release?
Ist Schlangengift tödlich oder hilfreich ?
Tja, auch bei Interfaces ist der manuelle Aufruf von ._Release() im Normelbetrieb meistens tödlich. Aber es gibt durchaus Anwendungsbereiche in denen die gezielte manuelle Benutzung sehr hilfreich, ja sogar notwenig wird. Zb. bei Listen oder zirkulären Verknüpfungen von Interfaces. Das heist ._Release() ist eine reguläre Methode eines Interfaces und kann manuell aufgerufen werden oder auch nicht. An der Methode selber ist nichts tödlich. Ob die manuelle Benutzung von ._Release() zu unschönen Seiteneffekten führt hängt nur vom Gesamtsystem ab. Delphi ist bemüht möglichst transparent im Hindergrund für dich das Referencecounting der Interfaces durchzuführen. Deine manuellen Aufrufe könnten also mit dem Delphi Mechanismen kollidieren, und das kann tödlich sein. Man kann aber durchaus Interfaces benutzen so das Delphi sich da nicht selber drum kümmert und dann ist ein Aufruf von ._Release; auch nicht mehr so gefährlich, weil wir ja nun sowieso alles manuell machen. Die Regeln wie und warum du ._Release nicht benutzten solltest werden also durch die Implementierungen im Compiler bestimmt. Benutzt du Interfaces in Delphi so übergibst du die komplette Kontrolle über das Lifetime Management der Interfaces dem Compiler. Der Compiler HAT sicherzustellen das dies sicher (try finally) und immer erfolgt. Deine Regel lautet: In Delphi werden Interfaces durch den Compiler verwaltet, das ist ein Vorteil für uns und wir mischen uns da nicht weiter ein (._Release), da das meistens nur zu Fehler führen wird. Wir müssen uns dann vergegenwärtigen was die Methode ._Release() für eine Sourcecode Entsprechnung besitzt. Diese Methode soll die Referenzzählung von Variablen die auf ds gleiche Interface zeigen durchführen. Eine Referenz ist also eine Variable die auf das Interface zeigt. Es können mehrere solche Variablen/Referenzen existieren. Was sind die Zuweisungs-Operatoren für Referenzen ??
Delphi-Quellcode:
Obige 3 Zeilen SIND die Zuweisungs-Operatoren. Mit ihnen verknüpft der Compiler beo Interfaces die Methoden ._Release() und ._AddRef(). Das erfolgt vollständig transparant, unsichtbar für dich durch den Compiler.var A,B: IInterface; begin A := CreateInterface; B := A; A := nil; end; Die Referenzzählung kann nur dann sauber funktionieren wenn der Delphi Compiler die komplette 1 zu 1 Kontrolle beim Mappen der Zuweisungsoperatorten -> := zu den Methoden ._AddRef()/._Release() der betroffenen Interfaces hat. Ein manueller Aufruf von ._Relase() würde demzufolgen nur eine halb-korrekte Zuweisungoperation von A := nil; darstellen. Dh. mit dem manuellen ._Release() zerstörst du die Logik die sich der Compiler mit seinen Zuweisungen aufgebaut hat. Klar, wenn man weis was der Compiler wie macht, wird auch ein manuelles ._Release() keinen Schaden anrichten, weil du dann weist das du vorher zu diesem ._Release() ein entsprechendes ._AddRef() aufgerufen hast. Die Benutzung manueller ._Release() Aufrufe ist also 1.) garnicht nötig in Delphi -> A := nil; macht das Gleiche und das viel sauberer 2.) nicht tödlich wenn vorher ein passendes ._AddRef() aufgerufen wurde, also der Programmierer weis was er tut 3.) unter bestimmmten Umständen, sprich zb. Listen, zirkuläre Referenzen, nicht zu vermeiden und daher wieder sinnvoll Gruß Hagen |
Re: := NIL ist gleich release?
Ich glaub die aussage mit dem :=nil war mehr auf die Sachen mit der Kompilermagig bezogen, denn wenn man z.B. ein dynamisches Array mit A:=nil löscht, geht es halt schneller, als der Aufruf von SetLength(A, 0), da beim Aufruf von A:=nil durch die CM intern direkt die Funktion zum löschen aufgerufen wird, was bei SetLength erst gemacht werd, wenn dieses die Lämge 0 erkennt und dann erst zum ClearArray (oder wie diese Funktion heißt) springt ... ansonsten wird meistens wirglich mit :=nil nur der Pointer auf die Daten gelöscht und nicht die Daten selber :)
|
Re: := NIL ist gleich release?
Hallo Hagen!
Danke für Deine Antwort... Witzig finde ich es nur, wenn ich C Source lesen, bei dem die Add und release Methode überschrieben ist mit einem Result immer result := 1; mfg Frank |
Re: := NIL ist gleich release?
@Mavarik:
deine Aussage verstehe ich nicht ganz, vermute aber das du auf den Fakt hinweisen möchtest das die letzendliche Implementierungen der Methoden ._AddRef() und ._Release() abhängig vom dem Interface selber sind. Dh. der Programmierer dieses Interfaces entscheidet wie sich das Interfaces beim Aufruf von ._AddRef() und ._Release() verhalten soll. Nun, meistens ist der Rückgabewert dieser Funktionen identisch zum internen Referenzzähler. Das bedeutet das die Funktion ._Release() eine 0 zurückgeben wird wenn das Object zerstört wurde. Und laut Definitionen die ich gelesen habe sollte ein Interfaces das Referenzzählung unterstützt mindestens <> 0 zurückgeben wenn das Interface noch lebt und immer 0 wenn das Interface zerstört wurde. Daraus folgt das Interfaces OHNE Referenzzählung immer 1 zurückgeben sollten. Bei Interfaces mit Referenzzählung könnte man also solange ._Release() aufrufen bis 0 zurückgegeben wird. Das ist aber in dem Moment gefährlich wenn das Interface eben keine Referenzzählung unterstützt und demzufolge immer 1 zurückgibt. Die Konvention bei ._AddRef()/._Release() nun den internen Zähler als Rückgabe zu benutzen hat den entscheidenden Vorteil das man mit einer Kombiation von ._AddRef() und ._Release() die Anzahl der Referenzen auf ein Interface in Erfahrung bringen kann. Man kann aber auch mit dem gleichen Vorgehen ermitteln ob ein Interface ein aktives Referencecounting unterstützt. Dh. sind die Rückgabewerte bei doppelten Aufrufen von ._AddRef() und ._Release() identisch so wird keine Referenzzählung unterstützt. Gruß Hagen |
Re: := NIL ist gleich release?
Zitat:
Gruß Hawkeye |
Re: := NIL ist gleich release?
Stimmt und zeigt sehr deutlich das es keinen konkreten Standard dafür gibt. -1 wird öfters gewählt weil dieser Wert als HResult(-1) ein Fehlercode ist.
Gruß Hagen |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:34 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