Autor Beitrag
KidPaddle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.02.06 12:33 
Hallo,

in einer Anwendung werden Daten in mehreren XML - Dateien mit TjvSimpleXML exportiert. Die XML - Dateien sind ca. 5MB groß und enthalten immer 5.000 Hauptknoten mit diversen Unterknoten. In einer Schleife wird die Ergebnismenge durchlaufen, es sind 280.000 Datensätze, und alle 5.000 Datensätze wird der XML-Tree in eine Datei geschrieben und mit XML.Root.Items.Clear werden die erstellten Knoten gelöscht.

Der Export funktioniert, nur schnellt der Speicherverbrauch extrem nach oben. Anscheinend wird der Speicher nach XML.Root.Items.Clear nicht freigegeben, sondern es wird weiter nur neuer Speicher reserviert. Pro 5000 XML - Knoten wächst dieser um ca. 100 MB!!!!!, so daß der Export bald abbricht.

Mein Frage ist, wie ich den ernormen Speicherverbrauch reduzieren kann, bzw. wie ich Delphi dazu bringen kann, das Root.Items.Clear den Speicher wieder freigibt.

Gruß
Thomas
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 10.02.06 12:51 
Was passiert, wenn du Root mit Free freigibts und danach wieder erstellst?
KidPaddle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.02.06 18:08 
Das hat keine Einfluss. Er gibt zwar in FastGetHeapStatus.TotalAllocated an, dass sich die Anzahl, bei Clear und Free, verringert, aber es wird kein physikalischer Speicher freigegeben.

Hier der Verlauf des Speichers nach jeweils 1.000 erstellten Knoten und Freigabe mit FreeAndNil des XML - Objektes.
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
  Speicherverbrauch vorher (1000 Knoten): 
    TotalAddrSpace:   19.922.944
    TotalUncommitted:    835.584
    TotalCommitted:   19.087.360
    TotalAllocated:    8.509.088
    TotalFree:         9.785.588
    FreeSmall:         9.744.056
    FreeBig:              41.496
    Unused:                    0
    Overhead:            792.644
  
  Speicherverbrauch nach FreeAndNil(): 
    TotalAddrSpace:   19.922.944
    TotalUncommitted:  1.474.560
    TotalCommitted:   18.448.384
    TotalAllocated:    4.280.568
    TotalFree:        13.895.920
    FreeSmall:         2.456.000
    FreeBig:          11.439.828
    Unused:                    0
    Overhead:            271.860


  Speicherverbrauch vorher (1000 Knoten): 
    TotalAddrSpace:   27.262.976
    TotalUncommitted:    999.424
    TotalCommitted:   26.263.552
    TotalAllocated:    9.987.488
    TotalFree:        15.443.376
    FreeSmall:        15.404.616
    FreeBig:              42.856
    Unused:                    0
    Overhead:            832.712

  Speicherverbrauch nach FreeAndNil(): 
    TotalAddrSpace:   27.262.976
    TotalUncommitted:  1.949.696
    TotalCommitted:   25.313.280
    TotalAllocated:    6.030.672
    TotalFree:        18.944.768
    FreeSmall:         5.629.164
    FreeBig:          13.315.580
    Unused:                    0
    Overhead:            337.860


  Speicherverbrauch (1000 Knoten): 
    TotalAddrSpace:   35.651.584
    TotalUncommitted:    770.048
    TotalCommitted:   34.881.536
    TotalAllocated:   12.666.012
    TotalFree:        21.246.444
    FreeSmall:        21.212.884
    FreeBig:              49.000
    Unused:                    0
    Overhead:            969.168

  Speicherverbrauch nach FreeAndNil(): 
    TotalAddrSpace:   35.651.584
    TotalUncommitted:  1.867.776
    TotalCommitted:   33.783.808
    TotalAllocated:    81.59.124
    TotalFree:        25.206.584
    FreeSmall:         9.810.516
    FreeBig:          15.396.068
    Unused:                    0
    Overhead:            418.100


Man sieht deutlich, das der Verbrauch immer größer wird, für mich sieht es so aus, das einmal reservierter Speicher nie wieder zugeteilt wird, auch wenn dieser mittlerweile freigegeben wurde.

Es macht übrigens keinen Unterschied, ob FastMM4 oder der Standard Memory Manager verwendet wird.

Gruß
Thomas
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 10.02.06 18:31 
Hast Du mal bei den JEDI-Leuten eine Anfrage gemacht, inwiefern die XML-Komponente ein MemLeak hat?

Hast Du XML oder XML.Root per FreeAndNil freigegeben?

Meldet FastMM4 beim Beenden des Programms im DebugMode MemLeaks?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
KidPaddle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: Fr 10.02.06 20:32 
Ich habe XML per FreeAndNil freigegeben und nicht XML.Root.

Den MemoryLeaks bin ich gerade auf der Spur, werde mich später dazu melden.

Gruß
Thomas
KidPaddle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 351

WinXP,Linux
D7 Prof, XE7
BeitragVerfasst: So 12.02.06 11:05 
Ich habe 3 Memory Leaks gefunden, wobei 2 unkritsch waren, eines in den Indy - Komponenten, eines in einer Skripting - Engine und ein nicht freigegebenes Dataset in einer Funktion. Da diese Funktion mehrere tausendmal aufgerufen wird, wuchs so der Speicher. Ich muste allerdings ersteinmal in der FastMM4 - Unit einen Stacktrace - Wert erhöhen, damit ich die Stelle herausbekam, wo der Fehler auftritt.

Danach war der Speicherverbauch stabil, aber trotzdem ernorm. Für den Export der 280.000 Datensätze werden ca. 250MB benötigt, es scheint irgendwie mit der Verarbeitung mit Strings zusammen zu hängen. Da es funktioniert und die Software nur wenigemal im Jahr benötigt wird, kann ich es akzeptieren, nur verstehen möchte es es gerne schon.

Gruß
Thomas