Seite 1 von 1

Protected String wird nach Endprocedure nicht freigegeben(?)

Verfasst: 30.05.2013 22:17
von Pseiko
Hallo,

ich kämpfe schon ein Weilchen mit einem Speicherleck. Hier der Versuch mein Problem in einem Minimalbeispiel zu verdeutlichen. Der Thread ist dabei, da er in meinem Programm auch vorhanden ist und ich das Problem zeitweise darauf zurückgeführt hatte. Jetzt bin ich einfach froh, dass es im Beispiel auch auftritt. Daher habe ich es einfach mal so gelassen.

Das Problem liegt darin, dass nach Beendigung der Prozedur der Speicher der Stringvariable offenbar nicht wieder freigegeben wird (lt. Taskmanager 50 MB(+) verwendeter RAM). Da die einzulesende Datei im Regelfall über 50 MB groß ist, natürlich etwas unschön.

Code: Alles auswählen

Global Teste.i = 1

Global Importdatei.s

Procedure Test()
  Protected Importstring.s
  Protected *Import
  ReadFile(1,Importdatei)
    *Import = AllocateMemory(Lof(1))
      ReadData(1,*Import,Lof(1))
  CloseFile(1)
  ImportString = PeekS(*Import,-1,#PB_UTF8)
  FreeMemory(*Import)
  Teste = 0
EndProcedure
      
Procedure Thread(Dummy.i)
  Delay(50)
  Repeat
    If Teste = 1
      Test()
    EndIf
  ForEver
EndProcedure
  
OpenWindow(#PB_Any,100,100,900,500,"Test")
Importdatei = OpenFileRequester("Test","","*.*",0)  
CreateThread(@Thread(),0)

Repeat
  Event = WaitWindowEvent(1)
  
Until Event = #PB_Event_CloseWindow 
Wenn

Code: Alles auswählen

ImportString = PeekS(*Import,-1,#PB_UTF8)
auskommentiert wird, ist alles in Ordnung.
Hat jemand eine Idee, wie ich die Problematik lösen könnte, bzw. wo ich einen Fehler in meiner Denke habe.

Ein

Code: Alles auswählen

Importstring = ""
am Ende der Prozedur hat leider auch keinen positiven Effekt.

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 22:42
von NicTheQuick
Hast du Threadsafe aktiviert?

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 22:43
von Pseiko
Ja.

Falls die Info was bringt: 64Bit-Compiler + Unicode

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 22:50
von uwe
Was du in jedem Fall vermeiden solltest, ist, in einem Thread GUI-Objekte - in deinem Fall OpenFileRequester() - zu erstellen. Besser wäre es, den OpenFileRequester über das Hauptanwendungsfenster zu starten und dann nur das Laden und Verarbeiten der Datei im Thread laufen zu lassen.

Ausserdem endet dein Thread nie. Wenn Teste=0 ist, läuft der Thread voll weiter und lastet einen CPU-Kern komplett aus. Benutze Delay(100) o.ä., um Rechenzeit zurückzugeben.

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 22:51
von Pseiko
Danke für den Hinweis. Ist allerdings nur in dem "zusammengeschusterten" Beispiel der Fall. In meinem Programm gibts den dort nicht.

Habe das Beispiel oben fix angepasst.

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 23:07
von STARGÅTE
Das Verhalten hat nix mit Threads oder Protected zu tun.

Das "Problem", wenn es denn eins ist, liegt in der Funktion PeekS() welche die 50MB in deinem Fall selbst noch im Buffer hat.

Hier ein einfacheres Beispiel:

Code: Alles auswählen

Space.s = Space(100*1024*1024)
Delay(5000)
Space = ""
Debug "nun sollte er weg sein"
Delay(50000)
Hier nutzt das Programm 200MB (für das Space() und für die Variable).
Nach der freigabe der Variable ist der Speicher in dem Space() die leerzeichen gemacht hat, immer noch reserviert (100MB).
Vermutlich damit solche Funktionen schneller sind, damit Space() sich nicht immer wieder neuen Speicher reservieren muss, sondern einfach den alten nutzt.

Und so ist es bei deinem PeekS()

Re: Protected String wird nach Endprocedure nicht freigegebe

Verfasst: 30.05.2013 23:26
von Pseiko
Ok, dann muss ich wohl "damit leben". Danke dir für die Erläuterung.