• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

llGetFreeMemory = "GarbageCollection" ?

argus Portal

Freund/in des Forums
Hallo

Ich mache die Beobachtung, das ein Script, das sich mit mit StackheapCollision verabschiedet, weiterläuft, wenn ich llGetFreeMemory() an der fraglichen Stelle aufrufe. Das ist reproduzierbar.

Kann das jemand erklären ?
 
Wirklich 100% nachvollziehbar ist das nicht. Du verwendest vermutlich Mono? Mono hat (im Gegensatz zu LSO) als VM tatsächlich eine Garbage Collection. Wann der Collector tatsächlich läuft weiß ich leider nicht, das wissen wohl nur ein paar Lindens genau ;-)

Mit Mono-Scripts hat das aber direkt nichts zu tun:So sind im Bytecode der Scripte ziemlich viele Stop-Codes einkompiliert, d.h. die Scripte machen nach fast jeder Funktion und jedem Event usw. einen kleinen Stop. So dass sie zu diesem Zeitpunkt "eingefroren", mit der atuellen Variablen-Belegung usw. abgespeichert und z.B. aus der VM genommen werden können um so auf dem Asset-Server zu landen (wenn man ein Script einpackt) oder um auf einem anderen Simulator in dir VM dort entpackt zu werden und dort an der Stelle nach dem Stop weiter zu laufen (bei einem TP oder beim Auspacken aus dem Inventory etwa). Und an jedem dieser Stops wird in Mono auch die Größe des vom Script belegten Speichers geprüft. Wie viel Speicher das Script zwischen den Stops belegt ist dabei egal (das können auch > 65kB sein) - aber beim Stop darf ein Script dann lediglich 64kB groß sein - sonst wird es von der VM einfach kurzerhand nicht weiter ausgeführt und die VM spuckt die Fehlermeldung "Stack/Heap Collision" aus - auch wenn es eigentlich gar keiner ist. Das ist lediglich die gleiche Meldung, die bei LSO-Scripts kam, wenn deren 16KB-Block zu voll war. Und an diesen Stops kann natürlich auch der Garbage Collector laufen. (Muss aber nicht).

llGetFreeMemory spuckt darüber hinaus auch lediglich aus wie viel Speicher vor der nächsten Garbage Collection noch frei ist, d.h. wie viel Speicher noch belegt werden könnte, bis das 64kB Soft Limit erreicht wurde. Da aber möglicherweise direkt im Anschluss tatsächlich der Garbage Collector laufen könnte kann es durchaus sein, dass eigentlich noch wesentlich mehr Speicher frei ist. Für Mono ist diese Funktion daher eigentlich unbrauchbar. Und in deinem Fall scheint es wohl so auszusehen als ob zufällig direkt davor der Garbage Collector gelaufen ist. Da das aber nicht gezwungenermaßen gleich passieren muss (in Mono ist der Garbage Collector je nach Version u.Umständen bisschen komplizierter...) ist ein Aufruf llGetFreeMemory verständlicherweise alles andere als eine saubere Lösung für dein Problem.

Du solltest also eher über llGetUsedMemory den momentan vom Script tatsächlich belegten Speicher zu kritischen Zeitpunkten abfragen oder aber über llScriptProfiler und llGetSPMaxMemory einmal ein Memory Profiling durchführen. Damit läuft das Script während des Profilings (also solange es nicht resettet wurde, die Region gewechselt hat, derezzt wurde usw.) zwar 100 mal langsamer - aber du kriegst damit raus wie viel Speicher dein Script während der bisherigen Laufzeit maximal belegt hat.

Alternativ kann man notfalls auch mit einem Stück Papier, einem Bleistift und einem Taschenrechner manuell berechnen wie viel Speicher dein Script zu welchem Zeitpunkt mindestens belegt. Siehe http://wiki.secondlife.com/wiki/LSL_Script_Memory
 
Zuletzt bearbeitet:
Danke für die Antwort. Das Speicherproblem ist wirklich eine nervtötende Angelegenheit, weil man zu Einschränkungen gezwungen ist. Aber vorwerfen kann man das LL natürlich nicht. Limits müssen sein. Ich forsche auf jeden Fall daran.


Zu deiner Frage: Ich nutze ausschliesslich MONO.

Da ich den Effekt per Zufall entdeckte und sich das reproduzieren liess, kam ich auf die Idee. Nach Zufall sieht das nicht aus.
 
(...)
Da ich den Effekt per Zufall entdeckte und sich das reproduzieren liess, kam ich auf die Idee. Nach Zufall sieht das nicht aus.

Es kann gut sein, dass das momentan immer so funktioniert, d.h. das gerade vor dem llGetFreeMemory() eine Garbarage Collection/Purge im Speicher der VM ausgeführt wird.
Nur: das ist kein im Wiki/in der Spec dokumentiertes Verhalten. Also sollte man es auch nicht verwenden. Denn es kann leider durchaus passieren, dass sich dieses Verhalten schon beim nächsten oder übernächsten Server-Update wegen irgendwelcher anderer Änderungen am Mono-System grundlegend ändert. Und schon gehen deine Scripte nicht mehr.

Wenn du wirklich in die Nähe der 64kB kommst mit deinem Script musst du eben dein Script so umbauen, dass es einfach weniger Speicher braucht. Oder du musst, sollte das nicht möglich sein, einfach einen bestimmten Teil in ein zweites Script auslagern, mit dem du dann z.B. über Link-Messages kommunizierst.
 
Meine Frage stellte ich aus rein technischem Interesse. Ausnutzen wollte ich den Effekt zumindest nicht ohne weitere Recherchen.

Dein Hinweis auf Auslagerung und Kommunikation mittels MessageLinked entspricht genau dem Prinzip, nach welchem ich in solchen Fällen vorgehe.
 
Meine persoenliche Schmerzgrenze bei Scripten ist 45000 bytes reinen Script-code.
Das heisst, ich frage im state_entry als letzten Befehl llGetFreeMemory ab und achte darauf, dass ich die 20000 bytes moeglichst nicht unterschreite.
Damit bin ich relativ auf der sicheren Seite auch wenn llGetFreeMemory nicht den genauen Wert wieder gibt, wenn das Script spaeter aufwendige Funktionen abruft. Dafuer ist ja der Script Profiler gedacht, wie von Shirley beschrieben.

LG
Dae
 

Users who are viewing this thread

Zurück
Oben Unten