HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

local leak?

12-22-2005, 09:36 AM#1
Thunder_Eye
Fast question:
Do locals leak as globals do?
12-22-2005, 09:39 AM#2
iNfraNe
locals leak when they are handles, they will prehibit wc3 from recycling the handleindex and that leads to a minor leak.

Is that what you mean? cus mostly leaks are about handles, not variables.
12-22-2005, 09:59 AM#3
Anitarf
As iNfraNe said, it's not the variables that "leak", it's the data you store in them: locations, unit groups,... those are often just temporary objects that are created and used by only one trigger. Those are the objects that "leak", because they are created, but not destroyed even when you no longer need them... unless you destroy them yourself. That's leak prevention, and is the same for objects stored in local and global variables.

However, there's one more trick with locals: they themselves are also just temporary entities, and due to some sort of bug object-local-variables (not integers, reals, strings and booleans) don't get cleaned at end of function, so they must be nullified manually (by setting them to null).
12-22-2005, 10:04 AM#4
Thunder_Eye
ok thank you
12-22-2005, 10:09 AM#5
Starcraftfreak
Another interesting thing I'd like to add is, that you can assign the value of a local handle-based variable to a global variable, which then holds the very same object. In this case you musn't destroy the object, but only nullify the local after the assignment to be able to use the global afterwards.

Does anyone of you guys have performance-numbers about nullifying vs. not nullifying?
12-22-2005, 10:13 AM#6
Blade.dk
Quote:
Originally Posted by Starcraftfreak
Does anyone of you guys have performance-numbers about nullifying vs. not nullifying?

I'll test it now, and post the results as soon as I'm finished testing.
12-22-2005, 10:22 AM#7
Anitarf
Quote:
Originally Posted by Starcraftfreak
Does anyone of you guys have performance-numbers about nullifying vs. not nullifying?
It's a small leak. The variable itself should be just 4 bytes (it's 16 by some estimates). The problem is with the handle stack. It is where all the handle objects are listed, each under a unique ID. Once an object is destroyed, it's handle index eventually gets recycled for a new object... but only if there are no variables pointing to it! So, by not nullifying a local, you are keeping a handle index "hostage" so it can't be recycled, and war3 needs to allocate new memory for increasing the handle stack.

This makes the leak from not nullifying not-so-insignificant, although it's still far from being as bad as if you didn't destroy the objects themselves. Many BJ functions have this leak, so GUI isn't safe from it even if it doesn't use locals, but as long as you destroy the locations and groups, this leak is insignificant enough to not cause any performance issues for GUI users. (but that's still no reason to not learn Jass :) )
12-22-2005, 10:33 AM#8
Blade.dk
Anitarf's right.

I also tested how much time the nullification took, called a funciton 5000 times, the function did a couple of things and created some objects and locals. The one test did nullify the locals the other one did not.

The difference between the two of them was so small that it was in the error range of the test (it was something like 0.1 seconds), so the nullification itself won't hurt.
12-22-2005, 10:36 AM#9
Vexorian
actually all references to a handle must be set to null after destroying it else they leak somehow , possibly blizzard has some kind of smart (maybe dumb) pointers that take 4 bytes of memory unless they are set to null. The problem is that blizzard forgot to derefference local variables automatically when functions end and that's the reason to set them to null.

If you destroyed a special effect that was pointed by a global you should set it to null too (although re setting the global to point another special effect also works)
12-22-2005, 01:28 PM#10
Starcraftfreak
I see. It's not that I don't set them to null, but I wanted to know why it leaks. Apparently Blizzard was not very smart when coding their smartass reference counter. A reference to a non-existant object is an invalid reference and thus should not count.

@Blade:
You might have to carry out a long-term test. Like performing the 5000 calls benchmark another 10-100 times. Additionally you might compare the memory usage.
12-23-2005, 12:12 AM#11
Anitarf
Quote:
Originally Posted by Starcraftfreak
I see. It's not that I don't set them to null, but I wanted to know why it leaks. Apparently Blizzard was not very smart when coding their smartass reference counter. A reference to a non-existant object is an invalid reference and thus should not count.
Nah, that's not so stupid, otherwise, if the handle index were recycled, the reference to a non-existant object would suddenly turn into a reference to an existant object. What blizz could do would be automatic nullification of all variables upon the destruction of the object they point to, or at least automatic nullification of local variables when a function finishes (I mean, it does that with parameters, why not locals?).
12-28-2005, 01:16 PM#12
Starcraftfreak
Quote:
Originally Posted by Anitarf
Nah, that's not so stupid, otherwise, if the handle index were recycled, the reference to a non-existant object would suddenly turn into a reference to an existant object. What blizz could do would be automatic nullification of all variables upon the destruction of the object they point to, or at least automatic nullification of local variables when a function finishes (I mean, it does that with parameters, why not locals?).
In the case of local variables it IS stupid, because they can't point to the new object anyways. There is no way to access a local non-nullified variable after the function terminates. In the case of a global that would be the case. But then again, when working with globals you should take care anyway. In properly-written code no problems would occur. I know what I'm talking about because I'm frequently abusing globals for different variable types and so a lot of typecasting occurs and you can never be sure what it was used last for.

As for the solution, you name it