AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi temporäre Interfaces sofort freigeben?

temporäre Interfaces sofort freigeben?

Ein Thema von himitsu · begonnen am 4. Jan 2010 · letzter Beitrag vom 4. Jan 2010
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.178 Beiträge
 
Delphi 10.4 Sydney
 
#1

temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 11:48
Warum gibt Delphi temporäre Interfaces nicht sofort wieder frei, wenn sie nicht mehr benötig werden?

Bei Strings und dynamischen Arrays versteh ich es ja, da so z.B. der Speicher nochmal verwendet werden kann.

Aber Interfaces verwalten ihren Speicher intern und können ihn garnicht weitergeben,
das heißt, selbst in einer Schleife und in der selben Temp-Variable würden die Interfaces immer wieder "freigegeben" und neu erstellt werden, selbst wenn sie gleich/identisch wären.

aus
Delphi-Quellcode:
for i := 1 to 1000 do
  IntToStr(i);
macht Delphi ja dieses.
Delphi-Quellcode:
var temp: String;

for i := 1 to 1000 do
  temp := IntToStr(i);
Ebenso ist es auch bei Interfaces.

sobald eine Funktion ein Interface als Result zurückliefert oder bei verschachtelten Aufrufen, wird ebenfalls eine temporäre Variable dafür angelegt.

aus [1]
XML.RootDocument.ChildNodes['xyz'].Attributes wird in etwa dieses [2]
Delphi-Quellcode:
temp1 := XML.RootDocument;
temp2 := temp1.ChildNodes;
temp3 := temp2.Nodes['xyz'];
temp3.Attributes
Das Problem da ist eine beschissene Speicher-/Referenzverwaltung ... vorallem bei verschachtelten Interfaces.
Dadurch wird eventuell nicht alles dort/dann freigegeben, wo man es "vermuten" würde.


So wurde bei mir z.B. das Document von MSXML dort freigegeben, wo ich es wollte, sondern erst bei Progammende (Consolenanwendung ohne Proceduren und Co., da eh alles Seriell abgearbeitet werden sollte).
Nach einem Hinweis auf dieses Verhalten wurde erstmal jeder größere Schritt in eine Prozedur ausgelagert, wo erstmal dieses Problem verteilt und jeweils bei Prozedurende passierte.

Über 'ne Laufzeitmessung der Prozedurenden, ein massives zerlegen des Codes, eigene temporäre Variablen mit manuell aus-NIL-setzen und vielen Versuchen konnte ich dieses Problem zwar bei mir beheben ... war wichtig 'ne Zeit-/Speichermessung in den einzelnen Programmschritten.

Aber eine gute Lösung ist das nicht wirklich, da der Code so unübersichtlicher wird, wenn man jetzt selber statt [1] nur noch die [2] selber macht.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Alaitoc

Registriert seit: 24. Okt 2008
263 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:09
Naja so wie ich das sehe werden Interfaces immer dann freigegeben wenn sie nicht mehr verwendet werden.
Wenn man z.b. für IXMLDomDocument eine Membervariable anlegt dann wird sie halt erst freigegeben, wenn
das Objekt an dem sie hängt zerstört wird oder sie explizit auf nil gesetzt wird.

Also in dem Fall:
Delphi-Quellcode:
type
  TBeispiel = class ( TObject )
    private
      m_IXMLDOMDOCUMENT: IXMLDOMDOCUMENT2;
    protected
      { Protected-Deklarationen } 
    public
      { Public-Deklarationen }
  end;
Und wenn sie innerhalb von Methoden verwendet werden, dann werden sie halt am Ende dieser freigegeben ( falls sie nicht irgendwie gesichert wurden z.b. ). Außer man sagt halt wieder explizit das man sie nicht mehr braucht per NIL.

Also in dem Fall:
Delphi-Quellcode:
procedure Beispiel;
var
  IXMLDOMDOCUMENT: IXMLDOMDOCUMENT2;
begin
  IXMLDOMDOCUMENT := coDOMDocument60.Create;
  IXMLDOMDOCUMENT.TUWAS;
end;
Ich halte das soweit für völlig sinnvoll, da Delphi sie halt erst freigibt wenn keine Referenz mehr vorhanden ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.178 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:18
Zitat von Alaitoc:
Naja so wie ich das sehe werden Interfaces immer dann freigegeben wenn sie nicht mehr verwendet werden.
Das ist leider ein kleiner aber feiner Irrtum.

Interfaces werden freigegeben, wenn es keine Variablen mehr gibt, wo eine Referenz von ihnen drinsteckt.
(Manipulationen der Referenzzählung mal ausgeschlossen)

[edit]
Beispiel kommt gleich


[edit]
das macht man, bzw. will man machen:
Delphi-Quellcode:
procedure Beispiel;
var
  xml: IXMLDocument;
begin
  xml := coDOMDocument60.Create;
  xml.RootDocument.TUWAS;
  xml := nil; // jetzt würde man denken hier würde alles freigegeben
end; // das passiert aber erst hier
das passiert aber:
Delphi-Quellcode:
procedure Beispiel;
var
  xml: IXMLDocument;
  {$delphiinten} tempnode: IXMLNode; {$ende}
begin
  xml := coDOMDocument60.Create;
  tempnode := xml.RootDocument;
  tempnode.TUWAS;
  xml := nil; // hier passiert nix, da tempnode noch existiert
               // und intern quasi noch eine Referenz auf das Dokument besitzt
end; // hier wird tempnode und erst jetzt erst auch das Dokument freigegeben
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Alaitoc

Registriert seit: 24. Okt 2008
263 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:19
Argh ja , das versuchte ich damit auszudrücken ^_°

Der Rest stimmt dann aber soweit denk ich x)

MfG Alaitoc
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.178 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:26
Schon OK, im Prinzip stimmt das ja soweit auch.

Nur gibt es da eben dieses klitzekleine Problem ... siehe mein Beispiel in Post #3
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:53
Aber innerhalb einer For-Schleife werden auch die Temps gelöscht
Delphi-Quellcode:
var IntfB:IIntfB;
    i:Integer;
begin

  for i:=1 to 3 do
  begin
    IntfB:=TIntfB.create;
    memo1.lines.add(inttostr(IntfB.IntfA.getNum));
    //IntfB:=nil; mit oder ohne
  end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Alaitoc

Registriert seit: 24. Okt 2008
263 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 12:56
Also wenn ich :

Delphi-Quellcode:
    
if ( GlobalReferenceCount = 0 ) and Assigned( GlobalXMLInterface ) then
    begin
      m_IXMLDocParser := nil; // Hier wird freigegeben
      GlobalXMLInterface := nil; // Hier kann ich nicht mehr auf die geladenen XML-Daten zugreifen
      inherited Destroy;
    end
Oder wie genau überprüfst du das? Hab mir da bisher noch nie so große Gedanken drüber gemacht

Und naja das zweite Beispiel ist mies, da müsste man sich was überlegen...vll irgendwie die Interfaces trennen oder so...

Delphi-Quellcode:
procedure Beispiel;
var
  xml: IXMLDocument;
  {$delphiinten} tempnode: IXMLNode; {$ende}
begin
  xml := coDOMDocument60.Create;
    TuWas(xml.RootDocument);
  xml := nil;
end;
Da dein Code aber sicherlich um einiges komplexer ist, ist es eine Herausforderung...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.178 Beiträge
 
Delphi 10.4 Sydney
 
#8

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 13:01
Zitat von sirius:
Aber innerhalb einer For-Schleife werden auch die Temps gelöscht
na das ist ja wohl klar, da dort natürlich immer wieder die selbe Temp-Variable verwendet wird
Delphi-Quellcode:
begin
  xml := coDOMDocument60.Create;
  for i:=1 to 3 do
  begin
    XML.RootDocument.ChildNodes.Nodes['xyz'].Attributes
  end;
  xml := nil;
end;

begin
  xml := coDOMDocument60.Create;
  for i:=1 to 3 do
  begin
    temp1 := XML.RootDocument;
    temp2 := temp1.ChildNodes;
    temp3 := temp2.Nodes['xyz'];
    temp3.Attributes
  end;
  xml := nil;
  // aber das letzte Interface bleibt dennoch bis zum Schluß in diese Variable drinnen.
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 13:09
Aus irgendwelchen Gründen (vielleicht um es einfach und/oder schnell zu machen) werden lokale (sichtbar oder nicht sichtbar=temporär) Variablen immer am Ende der Funktion gelöscht. Erscheint auch auf den ersten Blick recht logisch.

Und zu deinem Problem:
Tja, himi. Da würde ich sagen: Pech gehabt

Im Normalfall ist das Programm derart modularisiert, dass dieses Problem gar nicht erst sichtbar wird. Nur in deinem "Ausnahmefall" hast du ein Problem damit. Was hindert dich daran, dann eben temporäre Variablen sichtbar zu machen (wie du es schon schriebst). Für deinen fall musst du es eben so machen. Tausenden anderen wird dieses durch Delphi erspart.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
39.178 Beiträge
 
Delphi 10.4 Sydney
 
#10

Re: temporäre Interfaces sofort freigeben?

  Alt 4. Jan 2010, 13:19
@sirius: ein abschaltbares (gibt ja eh noch nicht genügend geheime Compilerschalter, also kommt es auf einen mehr nicht an) tempvar:=nil; nach gebrauch dieser Interface-Variablen würde vom "Tempo" her nicht viel nehmen und die paar Bytes mehr fallen in den größeren EXEen der neueren Compiler auch nimmer auf,
aber es würde die Speicherverwaltung und Referenzzählung IMHO verbessern.

Die Häufigkeit der Speicherverwaltung und damit das Tempo mag es vielleicht bei Strings und Co. verbessern,
aber bei Interfaces macht dieses eben keinen Unterschied, ob gleich oder erst später.


@Alaitoc:

Aufgefallen ist es praktisch durch dieses
http://www.delphipraxis.net/internal...t.php?t=170881

Code:
***** Test 1 ******************************************************************

fill MS-XML-DOM with 10.000 nodes and save this into a file
create:21  fill:13006  save:110  free:[color=#ff0000][b]0[/b][/color]
                                      [color=#0000ff]^ Zeit1[/color]

local free:[color=#ff0000][b]456[/b][/color]
           [color=#0000ff]^^^ Zeit2[/color]
bei diesem Code kommen die oben genannten Werte raus
- XML:=nil macht nix
- bei Prozedurende wird freigegeben
Delphi-Quellcode:
procedure Test;
  var XML: IXMLDocument;
    Node: IXMLNode;

  begin
    XML := coDOMDocument60.Create;
    XML.Version := '1.0';
    XML.StandAlone := 'yes';
    XML.Encoding := 'UTF-8';
    XML.AddChild('xml');
    for i := 0 to 9999 do
      XML.DocumentElement.AddChild(IntToStr(i));
    Start(Zeit1);
    XML := nil;
    Ende(Zeit1);
    Start(Zeit2);
  end;


Test;
Ende(Zeit2);
hier läuft es nun richtig
- bei XML:=nil wird freigegeben
- bei Prozedurende passiert (fast) nix mehr
Delphi-Quellcode:
procedure Test;
  var XML: IXMLDocument;
    Node: IXMLNode;

  begin
    XML := coDOMDocument60.Create;
    XML.Version := '1.0';
    XML.StandAlone := 'yes';
    XML.Encoding := 'UTF-8';
    Node2 := XML.AddChild('xml');
    Node2 := nil;
    Node := XML.DocumentElement;
    for i := 0 to 9999 do
      Node2 := Node.AddChild(IntToStr(i));
    Node2 := nil; // oder gleich mit in die Schleife ... ist ja soweit egal
    Node := nil;
    Start(Zeit1);
    XML := nil;
    Ende(Zeit1);
    Start(Zeit2);
  end;


Test;
Ende(Zeit2);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf