Fehler im String-Managment (PB 32bit)

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
matbal
Beiträge: 246
Registriert: 30.03.2011 20:53

Fehler im String-Managment (PB 32bit)

Beitrag von matbal »

Beim Untersuchen des Verhaltens von Space() bin ich auf einen ganz anderen Fehler gestoßen.

Im Beispielscode weise ich den Elementen eines Stringfeld erst große Strings zu. Anschließend lösche ich den Inhalt wieder, indem ich einen Leerstring zuweise. Damit sollte der Speicher der Stringverwaltung von PB wieder zur Verfügung stehen.

Bei sehr großen Strings scheint aber der freigegebene Speicher nicht wieder benutzt zu werden. Folgende Fehlermeldung erhalte ich: Ungültiger Speicherzugriff: (Schreibfehler an der Adresse 0). Der Fehler tritt nur in der 32-bit-Version auf.

Code: Alles auswählen

OpenConsole()

Define elemente = 1000000
Dim Zeile$(elemente)

Define fill$ = Space(1000000)
Define i

For i = 1 To elemente
   If i % 100 = 0 : PrintN(Str(i)) : EndIf
   
   Zeile$(i) = fill$
   Zeile$(i) = ""
Next i

PrintN("ENDE")
Das Problem tritt nicht auf, wenn ich fill$ nur 500000 Zeichen groß mache.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Fehler im String-Managment (PB 32bit)

Beitrag von NicTheQuick »

Auch unter Linux und 64-Bit läuft bei mir der Speicher langsam voll. Allerdings hört das Phänomen auf, nachdem ca. 3.8% meines RAMs von dem Programm belegt waren, da sind ca. 300 MB. Dann ist es nicht mehr gestiegen, aber das Programm lief trotzdem weiter.
Ich nehme an das liegt einfach daran wie PB seine Strings verwaltet. Aber ein Absturz sollte natürlich nicht passieren.

Zum Bug-Report selbst: Bitte in Zukunft folgenden Beitrag berücksichtigen: Wie melde ich einen Bug?
Bild
matbal
Beiträge: 246
Registriert: 30.03.2011 20:53

Re: Fehler im String-Managment (PB 32bit)

Beitrag von matbal »

Getestet habe ich nur unter Windows (WinXP und Win7x64).

Es scheinen alle 32-Bit PB-Versionen betroffen zu sein. (PB4.51, PB4.61, PB5.21 und die aktuelle beta)

Der Speicherverbrauch bleibt bei mir moderat. Bis zum Absturz (ohne Debugger) bzw. der Fehlermeldung (mit Debugger siehe oben) steigt er von 12MB auf 19MB. Das passiert beim mir unter XP, wenn i = 2000. Unter Win7 kurz nach 1900.
Demzufolge wird der Speicher zwar freigegeben, aber nicht wieder benutzt.


Ich habe zur Kontrolle mir noch die Stringadressen anzeigen lassen. Dabei fällt auf, daß sie, obwohl es wieder Leerstrings sind, trotzdem ungefähr 1 MB auseinanderliegen. Da der Adressraum der 32-Bit-Programm limitiert ist, ist es nachvollziehbar, daß das nicht lange gutgehen kann.

(Übrigens, wenn ich fill$ = Space(500000) setzte, liegen die Adressen nur 16 Bytes auseinander. Da wird also der freigegebene Speicher wieder benutzt.)

Code: Alles auswählen

EnableExplicit
OpenConsole()

Define elemente = 1000000
Dim Zeile$(elemente)

Define fill$ = Space(1000000)
Define i, adresse, alt

For i = 1 To elemente
   If i % 100 = 0 : PrintN(Str(i)) : EndIf
   
   Zeile$(i) = fill$
   Zeile$(i) = ""
   
   adresse = @Zeile$(i)
   Debug "Adresse: " + Str(adresse) + "   Diff: " + Str(adresse - alt) 
   alt = adresse
   
Next i

PrintN("ENDE")
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6994
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Fehler im String-Managment (PB 32bit)

Beitrag von STARGÅTE »

Das kommt mir bekannt vor:
http://www.purebasic.fr/german/viewtopi ... 74#p312974

Damals hatte ich die Annahme gemacht, das Space() den Seicher "behält" um schneller zu sein.
Das passt dann aber nicht mit dem neuen Code hier...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Taz
Beiträge: 27
Registriert: 20.01.2018 18:24
Wohnort: NRW

Re: Fehler im String-Managment (PB 32bit)

Beitrag von Taz »

Hallo, leider scheint sich nach gut 4 Jahren noch nichts geändert zu haben, werden Bugs überhaupt gefixt? :roll:

Mein System: Windows 7 x64, PB Version 5.61 x64

Kurzes Beispiel anhand von dem Ersten Post:

Code: Alles auswählen

EnableExplicit

CompilerIf #PB_Compiler_Debugger
	CompilerError "Disabled Debugger in toolbar"
CompilerEndIf

Prototype.i GetProcessMemoryInfo(hProcess.i, *ppsmemCounters.PROCESS_MEMORY_COUNTERS, cb.i)
Procedure.i GetProcessMemoryUsage(hPID)
	Protected Result.i, PMC.PROCESS_MEMORY_COUNTERS, GetProcessMemoryInfo.GetProcessMemoryInfo
	Protected Lib = OpenLibrary(#PB_Any, "psapi.dll")

	If Lib
		GetProcessMemoryInfo.GetProcessMemoryInfo = GetFunction(Lib, "GetProcessMemoryInfo")
		If GetProcessMemoryInfo(hPID, @PMC, SizeOf(PROCESS_MEMORY_COUNTERS))
			Result = PMC\WorkingSetSize
		EndIf
		CloseLibrary(Lib)
	EndIf

	ProcedureReturn Result / 1024
EndProcedure

Procedure Msg(Loop, Time)
	Static PID = 0
	If PID = 0 : PID = GetCurrentProcess_() : EndIf

	PrintN(RSet(Str(Loop), 7) + #TAB$ + RSet(FormatNumber(GetProcessMemoryUsage(PID), 0, ",", ".") + " K", 16) + #TAB$ + RSet(Str(Time), 10) + "ms")
EndProcedure


If OpenConsole()
	Define i, elemente = 1000000, fill$ = Space(1000000), Dim Zeile$(elemente), Timer.q = ElapsedMilliseconds(), TimeT.q = Timer

	PrintN("   Loops      MemoryUsage      duration for 10000 passes")
	For i = 0 To elemente
		If i % 10000 = 0
			Msg(i, ElapsedMilliseconds()-Timer)
			Timer = ElapsedMilliseconds()
		EndIf

		Zeile$(i) = fill$
		Zeile$(i) = ""
	Next i
	PrintN("Total Time: " + Str((ElapsedMilliseconds()-TimeT)/ 1000) + " seconds")
	Input()
EndIf
Ergibt bei mir folgendes:

Code: Alles auswählen

   Loops      MemoryUsage      duration for 10000 passes
      0         13.508 K                 0ms
  10000         92.400 K             30310ms
  20000        171.260 K             30105ms
  30000        250.128 K             30236ms
  40000        328.992 K             30315ms
  50000        407.860 K             30168ms
  60000        486.720 K             30248ms
  70000        565.592 K             30464ms
  80000        644.452 K             30280ms
  90000        723.320 K             30653ms
 100000        802.180 K             30208ms
 110000        881.052 K             30283ms
 120000        959.916 K             29828ms
 130000      1.038.784 K             29324ms
 140000      1.117.644 K             29611ms
 150000      1.196.548 K             29932ms
 160000      1.275.412 K             29819ms
 170000      1.354.280 K             29790ms
 180000      1.433.144 K             29835ms
 190000      1.512.008 K             29841ms
 200000      1.590.872 K             29879ms
 210000      1.669.740 K             29980ms
 220000      1.748.604 K             29994ms
 230000      1.827.468 K             30100ms
 240000      1.906.336 K             30089ms
 250000      1.985.200 K             30182ms
 260000      2.064.056 K             30197ms
 270000      2.142.924 K             30278ms
 280000      2.221.792 K             30571ms
 290000      2.300.660 K             31814ms
 300000      2.379.520 K             31397ms
 310000      2.458.392 K             31496ms
 320000      2.537.252 K             31449ms
 330000      2.616.120 K             31432ms
 340000      2.694.984 K             31699ms
 350000      2.773.852 K             31691ms
 360000      2.852.712 K             31660ms
 370000      2.931.580 K             31918ms
 380000      3.010.444 K             31806ms
 390000      3.089.304 K             31794ms
 400000      3.168.168 K             31820ms
 410000      3.247.036 K             32055ms
 420000      3.325.900 K             31938ms
 430000      3.404.764 K             32021ms
 440000      3.483.632 K             32074ms
 450000      3.562.496 K             32310ms
 460000      3.641.360 K             32881ms
 470000      3.720.224 K             32289ms
 480000      3.799.092 K             31172ms
 490000      3.877.956 K             31241ms
 500000      3.956.820 K             31319ms
 510000      4.035.688 K             31449ms
 520000      4.114.544 K             31541ms
 530000      4.193.412 K             31509ms
 540000      4.272.272 K             31578ms
 550000      4.351.148 K             31783ms
 560000      4.430.008 K             31933ms
 570000      4.508.876 K             31975ms
 580000      4.587.740 K             32056ms
 590000      4.666.608 K             32237ms
 600000      4.745.468 K             32288ms
 610000      4.824.340 K             32426ms
 620000      4.903.200 K             32623ms
 630000      4.982.068 K             32605ms
 640000      5.060.924 K             32749ms
 650000      5.139.792 K             32330ms
 660000      5.218.656 K             32355ms
 670000      5.297.520 K             33201ms
 680000      5.376.388 K             33284ms
 690000      5.455.252 K             33403ms
 700000      5.534.116 K             33571ms
 710000      5.612.980 K             33790ms
 720000      5.691.848 K             33832ms
 730000      5.770.712 K             33919ms
 740000      5.849.576 K             34074ms
 750000      5.928.444 K             34208ms
 760000      6.007.308 K             34301ms
 770000      6.086.168 K             34199ms
 780000      6.165.032 K             31962ms
 790000      6.243.900 K             31360ms
 800000      6.322.760 K             31316ms
 810000      6.401.628 K             31573ms
 820000      6.480.496 K             31646ms
 830000      6.559.364 K             31629ms
 840000      6.638.224 K             31762ms
 850000      6.717.096 K             31826ms
 860000      6.795.956 K             31941ms
 870000      6.874.824 K             31971ms
 880000      6.953.688 K             32096ms
 890000      7.032.556 K             32046ms
 900000      7.111.412 K             32199ms
 910000      7.190.276 K             32251ms
 920000      7.269.144 K             32417ms
 930000      7.348.008 K             32387ms
 940000      7.426.872 K             32428ms
 950000      7.505.740 K             32513ms
 960000      7.584.604 K             32593ms
 970000      7.663.468 K             32667ms
 980000      7.742.332 K             32774ms
 990000      7.821.200 K             32913ms
1000000      7.900.064 K             32853ms
Total Time: 3166 seconds
PB frist den ganzen Speicher... fast 8GB, für... 1 1mb string :shock:
Das kann doch so bestimmt nicht gewollt sein...

Ich habe mir mal den Spaß erlaubt, den Code mal fix in AutoIt zu schreiben:

Code: Alles auswählen

#include <String.au3>
Func _StrAddThousandsSep($vNumber, $sSeparator='.')
	Return StringRegExpReplace($vNumber, "\G\d+?(?=(\d{3})+(?:\D|$))", "\0"&$sSeparator)
EndFunc
Func Msg($Loop, $Time)
	Local $aData = ProcessGetStats()[0] / 1024
	ConsoleWrite(StringFormat("%7s\t%14s k\t %9ims\n", $Loop, _StrAddThousandsSep($aData), $Time))
EndFunc
Global $elemente = 1000000, $fill = _StringRepeat(" ", 1000000), $Zeile[$elemente], $Timer = TimerInit(), $TimeT = $Timer

ConsoleWrite("   Loops      MemoryUsage      duration for 10000 passes" & @CRLF)
For $i = 0 To $elemente - 1
	If Mod($i, 10000) = 0 Then
		Msg($i, TimerDiff($Timer))
		$Timer = TimerInit()
	EndIf

	$Zeile[$i] = $fill
	$Zeile[$i] = 0
Next
ConsoleWrite("Total Time: " & Int(TimerDiff($TimeT) / 1000) & " seconds" & @CRLF)
ConsoleWrite("AutoIt Version: " & @AutoItVersion & @CRLF)
While 1
	Sleep(25)
WEnd
Jetzt Das Ergebnis von dem AutoIt Programm:

Code: Alles auswählen

   Loops      MemoryUsage      duration for 10000 passes
      0         16.880 k                 0ms
  10000         17.060 k              6596ms
  20000         17.200 k              6763ms
  30000         17.520 k              6827ms
  40000         17.840 k              6966ms
  50000         18.160 k              6992ms
  60000         18.480 k              6792ms
  70000         18.800 k              6761ms
  80000         19.120 k              6807ms
  90000         19.380 k              6835ms
 100000         19.696 k              6744ms
 110000         20.016 k              6763ms
 120000         20.344 k              6718ms
 130000         20.664 k              6788ms
 140000         20.984 k              6712ms
 150000         21.312 k              6744ms
 160000         21.632 k              6936ms
 170000         21.952 k              7057ms
 180000         22.212 k              7052ms
 190000         22.532 k              6803ms
 200000         22.852 k              6851ms
 210000         23.180 k              6811ms
 220000         23.500 k              6937ms
 230000         23.820 k              6973ms
 240000         24.144 k              6914ms
 250000         24.464 k              6892ms
 260000         24.784 k              6760ms
 270000         25.040 k              6724ms
 280000         25.360 k              6941ms
 290000         25.680 k              7005ms
 300000         26.000 k              6768ms
 310000         26.324 k              6796ms
 320000         26.644 k              6758ms
 330000         26.964 k              6907ms
 340000         27.292 k              6723ms
 350000         27.612 k              6712ms
 360000         27.868 k              6729ms
 370000         28.192 k              6846ms
 380000         28.512 k              6782ms
 390000         28.832 k              6825ms
 400000         29.152 k              6803ms
 410000         29.472 k              6575ms
 420000         29.792 k              6664ms
 430000         30.116 k              6721ms
 440000         30.436 k              6580ms
 450000         30.696 k              6738ms
 460000         31.012 k              6858ms
 470000         31.332 k              6799ms
 480000         31.652 k              6844ms
 490000         31.976 k              6821ms
 500000         32.300 k              6846ms
 510000         32.620 k              6761ms
 520000         32.940 k              6771ms
 530000         33.260 k              6858ms
 540000         33.516 k              6885ms
 550000         33.836 k              6768ms
 560000         34.156 k              6678ms
 570000         34.480 k              6782ms
 580000         34.800 k              6843ms
 590000         35.120 k              6871ms
 600000         35.452 k              7032ms
 610000         35.772 k              6787ms
 620000         36.028 k              6703ms
 630000         36.352 k              6713ms
 640000         36.672 k              6868ms
 650000         36.992 k              7030ms
 660000         37.312 k              6784ms
 670000         37.632 k              6792ms
 680000         37.952 k              6699ms
 690000         38.276 k              6749ms
 700000         38.596 k              6824ms
 710000         38.852 k              6812ms
 720000         39.172 k              6736ms
 730000         39.492 k              6782ms
 740000         39.812 k              6826ms
 750000         40.132 k              7014ms
 760000         40.456 k              6888ms
 770000         40.776 k              6949ms
 780000         41.100 k              6815ms
 790000         41.420 k              6815ms
 800000         41.676 k              7041ms
 810000         41.996 k              6823ms
 820000         42.316 k              6792ms
 830000         42.640 k              6814ms
 840000         42.960 k              6880ms
 850000         43.280 k              7019ms
 860000         43.600 k              6850ms
 870000         43.920 k              6862ms
 880000         44.240 k              6790ms
 890000         44.500 k              6778ms
 900000         44.820 k              6793ms
 910000         45.140 k              6744ms
 920000         45.460 k              6903ms
 930000         45.780 k              6974ms
 940000         46.100 k              6694ms
 950000         46.420 k              6774ms
 960000         46.744 k              6805ms
 970000         47.064 k              6764ms
 980000         47.324 k              6870ms
 990000         47.644 k              6826ms
1000000         47.964 k              6861ms
Total Time: 682 seconds
AutoIt Version: 3.3.14.2
Zusammengefast:

Code: Alles auswählen

Purebasic Ramverbrauch: 7.900.064 K, Benötigte zeit: 3166 Sekunden
  AuotoIt Ramverbrauch:    47.964 K, Benötigte zeit:  682 Sekunden
Ein Armutszeugnis meiner Meinung nach, zu dem kommt noch, das AutoIt um einiges Schneller ist :o Aber keine Ahnung ob sich meinerseits ggf. Fehler eingeschlichen haben, bin noch neu was PB betrifft.

PS: Zum testen auch mal hier beide exe Dateien (beide in x64)
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Fehler im String-Managment (PB 32bit)

Beitrag von #NULL »

Probier's mal hiermit. Bei mir unter Linux wirkt das:

Code: Alles auswählen

   ...
   Zeile$(i) = fill$
   Zeile$(i) = #Null$
   ...
my pb stuff..
Bild..jedenfalls war das mal so.
Taz
Beiträge: 27
Registriert: 20.01.2018 18:24
Wohnort: NRW

Re: Fehler im String-Managment (PB 32bit)

Beitrag von Taz »

#NULL hat geschrieben:Probier's mal hiermit. Bei mir unter Linux wirkt das:

Code: Alles auswählen

   ...
   Zeile$(i) = fill$
   Zeile$(i) = #Null$
   ...
Tatsache :oops: :allright: Nur warum Braucht PB so lange?

Ich bin davon ausgegenagen, des es mit Null nicht funktioniert, weil ich es wo anders mit Null auch schon versucht hatte.
Hier mal der Code, hier verbleiben immer noch gute 200mb im ram übrig.

Code: Alles auswählen

EnableExplicit
Prototype.i GetProcessMemoryInfo(hProcess.i, *ppsmemCounters.PROCESS_MEMORY_COUNTERS, cb.i)
Procedure.i GetProcessMemoryUsage(hPID)
	Protected Result.i, PMC.PROCESS_MEMORY_COUNTERS, GetProcessMemoryInfo.GetProcessMemoryInfo
	Protected Lib = OpenLibrary(#PB_Any, "psapi.dll")
	If Lib
		GetProcessMemoryInfo.GetProcessMemoryInfo = GetFunction(Lib, "GetProcessMemoryInfo")
		If GetProcessMemoryInfo(hPID, @PMC, SizeOf(PROCESS_MEMORY_COUNTERS))
			Result = PMC\WorkingSetSize
		EndIf
		CloseLibrary(Lib)
	EndIf
	ProcedureReturn Result / 1024
EndProcedure

Procedure Msg(Text.s="")
	Static PID = 0
	If PID = 0 : PID = GetCurrentProcess_() : EndIf
	If MessageRequester("Info", Text + ~"\n\nCurrent MemoryUsage: " + FormatNumber(GetProcessMemoryUsage(PID), 0, ",", ".") + " K", 1) <> 1
		End
	EndIf
EndProcedure

Msg("create 'MyStr' now")
Define MyStr.s = Space(1024*1024*100) ; 100mb string
Msg("MyStr created, now clear the string")
MyStr = #Null$
Msg("After MyStr = #Null$")
Benutzeravatar
helpy
Beiträge: 635
Registriert: 29.08.2004 13:29

Re: Fehler im String-Managment (PB 32bit)

Beitrag von helpy »

Nebenbei ein kleiner Hinweis:

Code: Alles auswählen

Define MyStr.s = Space(1024*1024*100) ; 100mb string
Bei Unicode sind das 200 MByte!

Dass dadurch aber gleich 400 MByte belegt werden ist schon verdächtig!
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Antworten