My program is broken into about 8 different sub-modules. These all handle various parts of my program flow, such as reading configuration files, storing commonly-accessed data types, and so on. Well, I started noticing that one of my data storage scripts was leaking memory like a sieve. Upon every iteration of script states (from its "waiting for commands" to "go reload your config file" part), it was leaking around 1k!!
I know that llGetFreeMemory() is supposed (?) to return a low water mark, but I was clearing the only list that I use in the script every iternation. So I should have not ended up less free memory at the starting point every time around.
Further investigation found that my log function call was causing the memory leak! Here it is:
CODE
log (string msg)
{
llMessageLinked (LINK_SET, 8000, msg, "") ;
}
Now, that's just a convienence function, so I don't have to look at my script and go, "Uhh, what was listening for 8000 link messages?" I was willing to waste the heap space necessary for sending a string to a function, but I should have recovered that upon the function's return. Losing 1k for just a few log() calls didn't make any sense to me at all.
Long story short and many tests later, I found out that if you call a llSay(), llWhisper, llShout() or llMessageLinked() from a function -- the temporary string that appearently gets allocated for sending the message is never returned to the script heap pool! I know it's the string, because this code test shows consistant memory usage:
CODE
// Function leak-test, by Fenrir Reitveld
integer i ;
integer ii ;
leak_test (string in)
{
llSay (8128319, in) ; // send it out into the ether...
//llSay (0, " strlen: " + (string)llStringLength (in)) ;
}
default
{
state_entry()
{
llWhisper (0, "-->>" + (string)llGetFreeMemory()) ;
jump skip ; // <-- uncomment to show random memory leak
string temp ;
for (ii=0; ii < 50; ii++)
temp += (string)"^" ;
leak_test (temp) ;
@skip;
for (i = 0; i < 5; i++)
{
llSay (0, " " + (string) (i) + "> " + (string)llGetFreeMemory()) ;
string out ;
integer ii ;
for (ii= 0; ii < llFrand (50); ii++)
out += (string)"^" ;
leak_test (out) ;
}
llWhisper (0, "<<--" + (string)llGetFreeMemory()) ;
}
}
If I just insert the llMessageLinked()s right into my code in the appropriate states and ditch the function, there is no memory leak. I have not seen any other memory leakage related to running functions, either.
I really don't know if is a bug or not, or perhaps due to how functions are handled (being "stateless"
