HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Memory Leak FAQ

01-11-2004, 09:54 PM#1
Scarlet-Russian
This is a very pressing aspect of map development, so let's all pool what we know to make one solid FAQ on how to deal with this.

Here is what i know:

A memory leak happens when you fail to destroy something from the RAM (A computers quickly accesible memory). The negative side effects of this are:

1. Lower end PCs (with low amounts of RAM) begin lagging greatly when they run out of space because they start paging (redirecting) data to the harddreive which has noticably slower wrighting speeds than the RAM.

2. Exit lag is caused by this because Blizzard runs a "Garbage Collector" utility that removes all RAM entries from the map you have just played. Since there are "leaks" present in memory it takes a long time to clear them out.

Just chip in what you know and we cn make a solid FAQ!

Q: Do units set to a local variable cause memory leaks?
i.e.
Custom script: local unit udg_TempUnit
Set TempUnit = (Target unit of ability being cast)
Animation - Change TempUnit's vertex coloring to (50.00%, 100.00%, 50.00%) with 0.00% transparency
Unit - Add a 30.00 second Generic expiration timer to TempUnit
01-11-2004, 10:16 PM#2
weaaddar
local Handles are not cleared at the end of a function.

Your solution is to set the local var to null at the end of your function and have it return a primitive over a handle type. (Return bug if you need to return the handle).
01-11-2004, 10:36 PM#3
Cacodemon
I've post a thread about this in AI/JASS Vault (Advanced RB use). Setting handles to null doesn't solve problem just because handles are integers so setting them to null does really nothing - object which handle refers stay in memory and cause leak. Strings, reals cause leaks too and leaks caused by these types are unvoidable!. NULL is integer equal to 1, empty string always has handle equal to 0, so setting local handle to null DOESN'T clean memory! I've tested map where local objects were destroyed just before function returns. And there was no difference in memory / resources usage when handles point to taht object were destroyed or not. The only way to avoid leaks is to destroy object that handle refers.

This is the way to avoid leaks.... If you destroy every location, unit group etc. created inside your function, your function will not cause leaks.

Sometimes transferring handles to other functions is required so you have no reasons to destroy them. Then you should take care of and destroy them when you don't need these handles anymore...

P.S. Scarlet-Russian, please reply PM I've sent to you... emote_confused
02-23-2005, 08:07 AM#4
Jackyquah
Perhaps this could help. for location

try to call removelocation function after trigger done with location produced by GetUnitLoc or something to do with Getlocation.
because GetUnitLoc or something like that create Location, and will not be removed from memory before you call removelocation

Perhaps I could wrong but I think handle isn't cause memory leak. since it's just pointer
when we set varible like unit to something I think it's just set the pointer not create the object like createunit so I think it doesn't create memory leak.
perhaps, because the object that create by some function didn't remove from memory after being used.
02-23-2005, 08:31 PM#5
Vexorian
Quote:
Originally Posted by Cacodemon
I've post a thread about this in AI/JASS Vault (Advanced RB use). Setting handles to null doesn't solve problem just because handles are integers so setting them to null does really nothing - object which handle refers stay in memory and cause leak. Strings, reals cause leaks too and leaks caused by these types are unvoidable!. NULL is integer equal to 1, empty string always has handle equal to 0, so setting local handle to null DOESN'T clean memory! I've tested map where local objects were destroyed just before function returns. And there was no difference in memory / resources usage when handles point to taht object were destroyed or not. The only way to avoid leaks is to destroy object that handle refers.

This is the way to avoid leaks.... If you destroy every location, unit group etc. created inside your function, your function will not cause leaks.

Sometimes transferring handles to other functions is required so you have no reasons to destroy them. Then you should take care of and destroy them when you don't need these handles anymore...

P.S. Scarlet-Russian, please reply PM I've sent to you... emote_confused
Just to stop people from believing this.

You have to Destroy the object AND set the variable to null, both things leak.
07-05-2005, 02:39 PM#6
n7r3x
Quote:
Originally Posted by Lord Vexorian
Just to stop people from believing this.

You have to Destroy the object AND set the variable to null, both things leak.

what's the custom script for changing variables to null? and when do i need to put this script?
07-05-2005, 04:01 PM#7
Anitarf
Quote:
Originally Posted by N7r3x
what's the custom script for changing variables to null? and when do i need to put this script?

This is only needed with local variables, because they are not cleared at end of function. If you are using only GUI, then you needn't worry about seting variables to null, because global variables will eventually be reused to point to something else.
07-05-2005, 09:17 PM#8
mogmiester
how do you destroy a local unit? Remove unit? but that means you'd kill the unit youve just made :/ help please?
07-05-2005, 09:34 PM#9
Tim.
Quote:
Originally Posted by Anitarf
This is only needed with local variables, because they are not cleared at end of function. If you are using only GUI, then you needn't worry about seting variables to null, because global variables will eventually be reused to point to something else.

Why is it then when I use loops with GUI and Globals, that I also get memory leaks?

For example a loop every .10 seconds that uses globals checking if the left arrow key is pressed.
07-05-2005, 10:42 PM#10
Anitarf
Quote:
Originally Posted by mogmiester
how do you destroy a local unit? Remove unit? but that means you'd kill the unit youve just made :/ help please?
There is no such thing as a local unit, only a local unit variable. You must diferentiate between objects and variables (which are just pointers pointing to those objects). Because local pointers aren't cleared at end of function, they remain in memory if you do not set them to null, causing a minor leak, just a few bytes per pointer.

The main problem of memory leaks lies elsewhere. All objects, such as units, unit groups, locations, player forces,... are each stored under a unique handle, which is an integer number. These handles are stored in the handle index, and this is where your pointers (variables) point to.
Now, whenever a new object is created, a handle is also reserved for it, unless an already existing handle (which was created earlier for another object) can be recycled. A handle can only be recycled if the object stored there is destroyed and there are no pointers pointing to it.
Here is the catch. When you allow a pointer to stay in memory, it does not only take up those few bytes by itself, it also prevents a handle from being recycled, which is a lot more critical. If you have a Hero stored under that handle, then it doesn't matter much, because that hero is going to be around for the entire game, so his handle will never be a candidate for recycling anyway. However, if you keep creating lots of temporal objects such as locations, and you don't allow the handles of already used locations to be recycled for new ones, you are leaking a lot more memory.
As already stated, this is only critical with local variables that are used for temporal objects. Globals are not a problem because you keep re-using them, thus always seting them to point to some new object, allowing the handle of the old object (if it was destroyed properly) to be recycled. And don't worry about non-handle objects (such as boolean, integer (this are also item-types, unit-types), real), they don't leak.
07-06-2005, 08:26 AM#11
mogmiester
ok, sorry, but shouuld i remove a unit once it has died so its handle is recycled? or does wc3 automatically do that once it has died and decayed?
07-06-2005, 10:54 AM#12
EdwardSwolenToe
Once a unit has fully decayed, it is automatically removed from memory.
07-06-2005, 02:44 PM#13
weaaddar
No he isn't. He might be removed, but his reference may perpetuate if you dont' set his variable pointing to him to null. A reference handle can be quite big as discovered by cubasis.
07-06-2005, 02:57 PM#14
Vexorian
Quote:
Originally Posted by weaaddar
No he isn't. He might be removed, but his reference may perpetuate if you dont' set his variable pointing to him to null. A reference handle can be quite big as discovered by cubasis.
Yeah, and that's what caused the idea that RemoveUnit() leaked, but it was actually the index leaking.

Anyways I remember that someone pointed out that global variables needed to be set to null too, some years ago, anyways the thing was that globals would have to be set to null or be used to point something else or they will 'leak'
07-06-2005, 03:23 PM#15
weaaddar
right, but its global so we almost always assume people are going to reuse them when a unit dies. (Okay, I forget many people release shitty maps)