![]() |
MSXML und seine Speicherverwaltung?
Moin,
in meinem himXML hab ich unter anderem diesen TestCode (in CheckLibs.dpr)
Delphi-Quellcode:
nu hat jemand (samso) rausgefunden, daß dort die Interfaceverwaltung beim SimpleXML schlecht ist ... wodurch einige Objekte (vorallem SimpleXML und auch MSXML) nicht korrekt freigegeben wurden.
Var msXML: XMLDoc.TXMLDocument;
msNode: XMLIntf.IXMLNode; msXML := XMLDoc.TXMLDocument.Create(nil); Try msXML.DOMVendor := XMLDOM_Vendors[i4].Vendor; msXML.Active := True; msXML.Version := '1.0'; msXML.StandAlone := 'yes'; msXML.Encoding := 'UTF-8'; msXML.Options := [doNodeAutoIndent]; msXML.AddChild('xml'); For i := 0 to 9999 do msXML.DocumentElement.AddChild(Node_IntToStr[i]); Angeblich (laut Messung) ging das superflott innerhalb von etwa 0 ms , aber nun stellte sich raus, daß die Objekte garnicht freigegeben wurden. Zitat:
bei mir sah/sieht es im Testprojekt so aus
Delphi-Quellcode:
(aber mit dem Hauptproblem der Interfaceverwaltung hat es nichts zu tun)
For i := 0 to 9999 do Begin
siNode := SimpleXML.CreateXmlElement(Node_IntToStr[i]); siXML.DocumentElement.AppendChild(siNode); End; Zitat:
Delphi-Quellcode:
Nachdem ich nun selber nochmal alles umgestellt und auch mal die Zeit für das Ende ( end. ) der einzelnen Prozeduren mitgemessen hatte, stellte sich der Selbe Effekt auch beim MSXML raus, aber leider komme ich hier nicht weiter :wall:
Var msXML: XMLDoc.TXMLDocument;
msNode: XMLIntf.IXMLNode; msXML := XMLDoc.TXMLDocument.Create(nil); Try msXML.DOMVendor := XMLDOM_Vendors[i4].Vendor; msXML.Active := True; msXML.Version := '1.0'; msXML.StandAlone := 'yes'; msXML.Encoding := 'UTF-8'; msXML.Options := [doNodeAutoIndent]; msNode := msXML.AddChild('xml'); msNode := nil; For i := 0 to 9999 do msNode := msXML.DocumentElement.AddChild(Node_IntToStr[i]); msNode := nil; Im Obrigen Code hab ich nurn also mal alle "temporäten" Variablen entfernt, durch eigene ersetzt und diese manuell freigegeben:
Delphi-Quellcode:
so weit so gut ... nur gibt es jetzt ein "klitzekleines" Problem, denn es läuft nichts mehr :shock:
Var msXML: XMLDoc.TXMLDocument;
msNode: XMLIntf.IXMLNode; msXML := XMLDoc.TXMLDocument.Create(nil); Try msXML.DOMVendor := XMLDOM_Vendors[i4].Vendor; msXML.Active := True; msXML.Version := '1.0'; msXML.StandAlone := 'yes'; msXML.Encoding := 'UTF-8'; msXML.Options := [doNodeAutoIndent]; msNode := msXML.AddChild('xml'); msNode := nil; For i := 0 to 9999 do msNode := msXML.DocumentElement.AddChild(Node_IntToStr[i]); msNode := nil; msXML läßt sich so nicht als IXMLDokument (Interface) nutzen, da ich noch keine andere Möglichkeit fand dort den DOMVendor anders zu nutzen. Probem ist jetzt, sobald der Rootnode, welcher von msXML.AddChild('xml') zurückgegeben wird, freigegeben wurde, wird auch das ganze Dokument freigegeben und es kommmt beim Erstellen des ersten Nodes innerhalb der Schleife zu einer Exception. :shock: :wall: Zitat:
Delphi-Quellcode:
aber auch hier wird das Dokument noch nicht dort Freigegeben wo es sollte (<< free) . :?
Var msXMLc: XMLDoc.TXMLDocument;
msXML: XMLIntf.IXMLDocument; msNode: XMLIntf.IXMLNode; msXMLc := XMLDoc.TXMLDocument.Create(nil); Try Try msXMLc.DOMVendor := XMLDOM_Vendors[i4].Vendor; msXMLc.Active := True; msXMLc.Version := '1.0'; msXMLc.StandAlone := 'yes'; msXMLc.Encoding := 'UTF-8'; msXMLc.Options := [doNodeAutoIndent]; Finally msXML := msXMLc; End; msNode := msXML.AddChild('xml'); msNode := nil; For i := 0 to 9999 do msNode := msXML.DocumentElement.AddChild(Node_IntToStr[i]); msNode := nil; msXML.SaveToFile(ChangeFileExt(ParamStr(0), '.Test1_MSXML.xml')); msXML := nil; // << free Except On E: Exception do Begin WriteLn(E.Classname, ': ', E.Message); msXML := nil; End; End; so geht es ebenfalls nicht
Delphi-Quellcode:
msNode := msXML.AddChild('xml');
msNode := nil; For i := 0 to 9999 do Begin msNode := msXML.DocumentElement.AddChild(Node_IntToStr[i]); msNode := nil; End; msXML.SaveToFile(ChangeFileExt(ParamStr(0), '.Test1_MSXML.xml'));
Code:
***** Test 1 ******************************************************************
fill TXMLFile with 10.000 nodes and save this into a file create:8 fill:7 save:4 free:3 fill MS-XML-DOM with 10.000 nodes and save this into a file create:21 fill:13006 save:110 [color=#ff0000]free:0[/color] [color=#ff0000]local free:456[/color]
Code:
ohne MSXML wird die Prozedur schnell beendet, also wurde irgendwas vom MSXML nicht freigegeben
***** Test 1 ******************************************************************
fill TXMLFile with 10.000 nodes and save this into a file create:0 fill:7 save:6 free:3 [color=#ff0000]local free:0[/color] und ich finde einfach nichts mehr ... keine weitere Prozedur hat noch einen Rückgabewert mit 'nem Interface, welche von Delphi als "temporäre" Variable gepsichert und somit erst bei Prozedurende, wo dann auch alle temporären Variablen freigeben werden, welche wie lokale Variablen behandelt werden ... zumindestens finde ich Keine. |
Re: MSXML und seine Speicherverwaltung?
Geht es so?:
Delphi-Quellcode:
N.B. Zu der Änderung "AppendElement". Dies bezieht sich auf meine geänderte Version von SimpleXML.pas. Bei der alten Version wurde per Default eine globale Namenstabelle benutzt. Das fand ich nicht so toll, weil verschiedene XML-Dateien ja nun nicht unbedingt die gleichen Namen benutzen. Bei meiner Version wird mit einem neuen Dokument auch eine neue Namenstabelle angelegt. Wenn nun ein Element "offline" erzeugt wird, erhält dieses Element eine eigene Namenstabelle. Beim Einhängen des Knotens werden dann die beiden Namenstabellen zusammen geführt. Ein unnötiger Schritt, der bei "AppendElement" vermieden wird. Aber wie gesagt - bezieht sich auf meine Version und nicht auf das Original aus dem Jahr 2003.
msRoot := msXML.AddChild('xml');
For i := 0 to 9999 do Begin msNode := msRoot.AddChild(Node_IntToStr[i]); msNode := nil; End; msXML.SaveToFile(ChangeFileExt(ParamStr(0), '.Test1_MSXML.xml')); msRoot := nil; msXML := nil //<- Hier würde ich jetzt das freigeben erwarten |
Re: MSXML und seine Speicherverwaltung?
Also ... ich bin noch beim Testen, aber der Fehler lag wohl z.B. hier
Code:
für das verschachtelte DocumentElement legt Delphi auch eine "temporäre" Variable an, welche es nicht gleich wieder freigibt :wall:
msXML.[b]DocumentElement[/b].AddChild
Und da sage mal wer, daß Interaces soooooo cool wären. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:54 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