Verfasst: 23.01.2006 21:18
Hi ts-soft,
Die angegebenen Werte stellt die im Taskmanager angezeigte Speicherauslastung des Programmes dar (jeweils abgelesen, wenn die MessageBox erscheint).
Da ist zu erkennen, dass der Speicherverbrauch nicht höher ist, gleichgültig ob die einzelnen Array-Elemente mit dem String "test" oder mit dem Null-String "" gefüllt wurden. D.h. Auch ein Nullstring braucht eine bestimmte Menge an Speicherplatz!
Erst wenn das ganze Array gelöscht wird, wird auch der Speicherplatz für die Strings freigegeben.
JA! Beim Programmende wird Speicher wieder freigegeben! Aber stell Dir eine Anwendung vor, die einen ganzen Tag (oder auf einem Server sogar mehrere Tage) läuft, dann muss eine eigene Aufräumroutine geschrieben werden, die es ermöglicht dynamisch erzeugte Strukturvariablen mit Strings wieder freizugeben. Anders sehe ich zur Zeit keinen Ausweg!
Beispiel:
Das funktioniert so recht gut! Nachteil ist, dass man auf die Strings über Peeks zugreifen muss.
Die Funktion von remi_meier scheint auch zu funktionieren. Gibt es jedoch mehrere Strings in einer Struktur, muss die Funktion FreeStructuredString auch für jedes Struktur-Element vom Typ String aufgerufen werden!
cu, helpy
JA! Stimmt!ts-soft hat geschrieben:PB gibt am Programmende den kompletten Stringspeicher frei, ...
JA! Stimmt!ts-soft hat geschrieben:... sowie alle anderen Speicher auch.
Das stimmt so nicht ganz! Der String ist zwar leer! Aber es ist immer noch Speicherplatz für den String reserviert! Das kann man mit folgendem Test nachweisen:ts-soft hat geschrieben:Strings können während des Programmlaufs nur durch Zuweisung eines Nullstrings ("") gelöscht werden.
Code: Alles auswählen
MessageRequester("test","Start of Program")
; => 2.4 MByte
Dim aString.s(1024*1024)
MessageRequester("test","Dim aString.s(1024*1024)")
; => 2.5 MByte
For i = 0 To 1024*1024
aString.s(i) = "Test String"
Next i
MessageRequester("test","Array filled with Strings")
; => 23.0 MByte
For i = 0 To 1024*1024
aString.s(i) = ""
Next i
MessageRequester("test","Strings in Array are cleared with NULL string")
; => 23.0 MByte
Dim aString.s(0)
MessageRequester("test","Array is set to size ZERO!")
; => 2.6 MByte
Da ist zu erkennen, dass der Speicherverbrauch nicht höher ist, gleichgültig ob die einzelnen Array-Elemente mit dem String "test" oder mit dem Null-String "" gefüllt wurden. D.h. Auch ein Nullstring braucht eine bestimmte Menge an Speicherplatz!
Erst wenn das ganze Array gelöscht wird, wird auch der Speicherplatz für die Strings freigegeben.
Stell Dir vor Du hast mehrere dynamisch allokierte Speicherbereiche und willst nur einen davon freigeben! Um die Daten der anderen Speicherbereiche nicht zu verlieren, kann ich FreeMemory(#PB_Any) nicht verwendet.ts-soft hat geschrieben:Im Zweifelsfalle mach einfach FreeMemory(#PB_Any)
JA! Beim Programmende wird Speicher wieder freigegeben! Aber stell Dir eine Anwendung vor, die einen ganzen Tag (oder auf einem Server sogar mehrere Tage) läuft, dann muss eine eigene Aufräumroutine geschrieben werden, die es ermöglicht dynamisch erzeugte Strukturvariablen mit Strings wieder freizugeben. Anders sehe ich zur Zeit keinen Ausweg!
Beispiel:
Code: Alles auswählen
#TEST_LOOP = 1024*1024
Structure TEST_STRUCT
ps.l
x.l
y.l
EndStructure
Procedure CreateString(*s)
Protected PointerToString, LenOfString
LenOfString = MemoryStringLength(*s)
PointerToString = AllocateMemory(LenOfString+1)
If PointerToString <> 0
CopyMemory(*s,PointerToString,LenOfString)
EndIf
ProcedureReturn PointerToString
EndProcedure
Dim *test.TEST_STRUCT(#TEST_LOOP)
MessageRequester("TEST","Array is ready!")
For i = 1 To #TEST_LOOP
*test(i) = AllocateMemory(SizeOf(TEST_STRUCT))
If *test(i) <> 0
*test(i)\ps = CreateString(@"Ein Test")
EndIf
Next i
MessageRequester("TEST","Memory allocated and assigned to array!")
Debug PeekS(*test(1)\ps)
Debug PeekS(*test(1000)\ps)
Debug PeekS(*test(1000000)\ps)
For i = 1 To #TEST_LOOP
FreeMemory( *test(i)\ps )
FreeMemory( *test(i) )
Next i
MessageRequester("TEST","Memory is free again!")
Die Funktion von remi_meier scheint auch zu funktionieren. Gibt es jedoch mehrere Strings in einer Struktur, muss die Funktion FreeStructuredString auch für jedes Struktur-Element vom Typ String aufgerufen werden!
cu, helpy