What does this mean?
Is this a recursion problem?
Memory issue?
Code size is > 800 lines of code, is that an issue?
These forums are CLOSED. Please visit the new forums HERE
Stack-Heap Collision |
|
|
blaze Spinnaker
1/2 Serious
Join date: 12 Aug 2004
Posts: 5,898
|
08-25-2004 16:31
What does this mean?
Is this a recursion problem? Memory issue? Code size is > 800 lines of code, is that an issue? |
|
blaze Spinnaker
1/2 Serious
Join date: 12 Aug 2004
Posts: 5,898
|
08-25-2004 16:33
This error occurs when the script runs out of memory (the stack and heap pointers, which count from opposite directions meet in the middle, thus the name stack/heap collision). To avoid this, check the available memory before doing any memory-intensive calls using llGetFreeMemory.
LSL scripts are currently allocated 16kb of memory each, in which the compiled scripts bytecode and the above mentioned stack and heap are stored. Ways to conserve memory: * Check your scripts for recursive function calls - an infinite recursion will fill the stack and cause this error. * Lists use alot of memory. Sometimes it's possible to use a string instead (also see CSV). * Split your large script into multiple scripts that communicate using LinkMessages. Ugh. Where does badgeometry get their info? |
|
Catherine Omega
Geometry Ninja
Join date: 10 Jan 2003
Posts: 2,053
|
08-25-2004 17:40
Originally posted by blaze Spinnaker Where does badgeometry get their info? From what parts of the official documentation aren't actually lies in diguise, from years spent harrassing the Lindens, and through trial and error. If you see something that's wrong, by all means, add a correction. _____________________
|
|
blaze Spinnaker
1/2 Serious
Join date: 12 Aug 2004
Posts: 5,898
|
08-25-2004 18:11
Perhaps they could buy it off of you?
|
|
Another Fool
Junior Member
Join date: 16 Aug 2004
Posts: 1
|
08-25-2004 18:29
From my best guess, the script memory model looks something like this:
+------------ | Stack +------------ | Heap +------------ | LSL ByteCode +------------ The heap & byte code are largely static (lists and strings can change this). The stack grows and shrinks as your program runs. Ways to conserve memory: + Deinitialize your heap variables. Have a list you don't need any more? Set it equal to []. Set strings to "". This will give you additional space for calculations. This isn't worth it for types with a static length, like floats, ints, vectors or rotations. + Make your code compact. If you have a segment of code you use often, put it in a function. Remove needless stuff. Compile without debug printing. + Put more stuff in the stack. Using local variables will let you recycle the stack space. + Avoid recursion. There is no recursive function that cannot be transformed into an iterated one. Construct a stack using a list/string and do your stuff there. + Remove unused/redundant constants. + Avoid lists. They suck, and have a huge memory and time cost. Instead, try to pack things into strings using some encoding. This may be a bit more difficult, but the payoff is usually worth it. A single integer in a list can cost as much as 40 bytes. |
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
01-23-2006 20:22
Hi,
Background: I've got a script thats been work, but growing in size over time, and I'm now hitting/getting an "Stack-Heap Collision". Assuming I've followed the coding tips (re lists, recursion etc) what sorts of approaches do people use/recommend: [1] States/Global Variables - I have several logical states within the script design which I model via the LSL states. The first few use/share several lists that therefore have to be GLOBAL. Would the general required approach here be to merge the 3 states into 1 state? This would be a bit messy from a script maintenance/easy-of-understanding point of view, but the lists could then be non-GLOBAL. Alternatively (maybe better) maintain multiple states but reset the lists after getting past the first 3 states to []? [2] Ways to split off into different scripts - I don't have many procedures (as opposed to functions) that can be split out. The main approach for my script would seem to be breaking some of the states out (e.g. state 1-3 in one script, states 4-8 in a second script), again a little messy though. Any comments here re whether splitting a larger script into multiple smaller scripts based on state is a good idea or not? Tks |
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
01-24-2006 01:50
It's an 'it all depends' type of question, like how long is a piece of string.
I went through a phase of using states, and although I still do occasionally by and large I don't use states at the moment in my scripting as I found too many weird problems for end users with them. Whilst I could be self-righteous and say it's because they don't read the instructions (usually true) making it simpler to use and making it easy to use is part of my whole approach to scripting. As for splitting scripts and state sets between different scripts I don't see that as a problem in most structuring, especially when you're having stack-heap collisions. States are, by their nature, separate entities after all, you're simply changing them from being distinct within a script to really distinct, in separate scripts. One thing this might well do is make you consider what data actually needs to be passed to each state - you might well be wonderfully self-disciplined and not just store it all, all the time, but I know I'm not. State A needs data a, b, c state B needs b, c, d, e, so I'll store all of a-e all the time... It's easier but it chews memory. Split between different scripts I'll use a link message (or 2) to pass a, b, c to script A and different ones to pass b, c, d, e to B (and if I'm really thinking smartly I'll use one for a to A, one for b, c to A and B, and one for d, e to B!). If you end up using globals is there a really pressing reason why you need lists? Lists have a maintenance cost (in terms of memory) associated with them - using separate globals where possible actually makes things less memory hogging (and easier to read for most people). Sometimes, of course, it's the only way but it does need thinking about. Sorry if that's not really answered your question. Anything complex enough it has several states will have a multitude of decisions associated with it about structuring etc. and they'll vary from case to case. It makes it a question that has no clear-cut answer. |
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
01-24-2006 02:19
Thanks Eloise - I'm fishing for ideas mainly so your response helps. I do use small lists mainly as a means for generic configuration of my application. It'll have to put some more llGetMemory debug points in to verify but I think my script is mainly suffering from the size it's grown to. Some questions for anyone:
a) Is there a rough rule of thumb for how many lines an LSL script can be prior to it typically having to be split out due to memory reasons? The one I have is about 800 lines at the moment - perhaps I shouldn't have admitted to that ![]() b) If I do want to use lists (e.g. and sort capabilities in some cases) is it better having say 2 lists, or 1 strided list? i.e. from a memory usage point of view. Tks |
|
gene Poole
"Foolish humans!"
Join date: 16 Jun 2004
Posts: 324
|
01-24-2006 05:07
I'm not trying to be a smart-ass, Greg, but there's llGetFreeMemory() -- why don't you write two versions of your script (or just some basic test script), one with 2 lists, the other with a strided list, and compare the free memory? Then post your results (here, and in the wiki).
Doing more than 2 (3, 4, etc) will give further results that can allow you to intuit the expected behaviour with reasonable accuracy.Do note the weird behaviour of llGetFreeMemory() so you can take it into account with your test script. |
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
01-24-2006 12:13
tks - good idea
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
01-31-2006 21:44
just clarifying:
It should be the case that every time you enter the main event loop of a state, that assuming the code in the event is not increasing the size of global variables [e.g. may be changes them though], that the llGetMemory() call should remain the same over time no? Is this correct? Are there any known ll* functions that don't adhere to this, such that the more you call them the more memory you lose for the script? |