• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[General] I've been wondering about leaks...

Status
Not open for further replies.
Level 7
Joined
May 13, 2011
Messages
310
OK, before I start, I don't want people to read the title and post links to stuff like this. I have read that.

What I want is to make sure that I get what leaks are in Warcraft 3, what kind of things leak and what I should do about them. Therefore I have prepared a few questions. I would like people to answer these questions only, and not write massive walls of text loosely explaining leaks in a very plain and confusing way.

Now that that's clear, here are my questions:

  1. Leaks are (basically) variables that are not being used or going to be used and are simply taking up memory, thus causing lag. Is that correct?
  2. Are variables the only things that leak? Do hashtables leak? Do arrays leak?
  3. I have heard that things like Locations and Unit Groups leak. What other kind of variables leak?
  4. How do I remove leaks? I know of JASS such as RemoveLocation(), but what JASS/GUI functions can I use for each type of leak, and how do I use them (if there is a specific way)?
  5. Does JASS leak more than GUI, vice versa, or doesn't it matter?
  6. Any special tips I should know about leaks?

Thanks a heap guys!
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
  1. Variables that you cannot any longer access/use. That's one type of leak.
  2. Arrays are one form of variable, so yes, they can leak if they are local. Hashtables globally store data, so you cannot really lose access but they have a large domain (keys you can use), and you may forget where you saved the data, therefore practically never releasing them. Also you can have up to 255 hashtables.
  3. First, you have to differentiate between objects and variables and there are primitive variables and object variables. Every object that you can instantiate and forget to delete may cause a leak. Primitive data like integers or real hold the information themselves and are always automatically get rid of. Handles like units are referenced by variables, means the variable only points to the object, multiple variables can point to it and you would not want the unit to have killed/copied. Then again, interactive objects like units are an exception, you might not keep them in variables in jass but they may be terminated by the normal engine (like the unit decays after a time after dying) or they are revealed again when running across a jass event (e.g. A Unit acquires an Item-event).
  4. Most object types that you can create have deconstructors like the one you mentioned. They often start with Remove or Destroy in name. They are a way to prevent object leaks. But these objects are still not completely removed until you reset all variables pointing to them. Global variables or hashtable entries may be reset at some later point in time when you overwrite them but there are local variables that are only declared within a function call, means that variables get dynamically created ingame and are killed at the end by the engine. However, these variables won't automatically be freed from their object values, therefore the objects you stored in them cannot be laid to rest unless you reset the variables manually. That's why local variables should be nulled in the end (objectVar = null)
  5. In GUI, you do not get to see much of the structure. You are not allowed to create all kinds of objects, nor to delete everything. Locations are wide-spread in GUI, they can only be created. In jass, you will hardly use locations at all because there are mostly x/y-real-coordinate variants for the functions, so you do not need a location object.
  6. Understand what a leak is instead of panicking around because someone shallowly mentioned what evil things they are. You cannot avoid all leaks because there are some within the engine. The general idea is to manage your data, your physical memory has limited capacities, so throw things away that you do not need any longer, it's also a matter or orderliness. The existence of hardware restrictions means that not every lag/performance drop originates from leaks. If you are using GUI, I would not advice you to insert custom scripts just to "remove leaks" unless it's noticeable ingame. GUI is already very inefficient in comparison to jass and the mix gets ugly.
 
Level 7
Joined
May 13, 2011
Messages
310
What I managed to deduce from your post was this: remove/nullify all variables that I won't/can't access later on. Is that the gist?

First, you have to differentiate between objects and variables and there are primitive variables and object variables. Every object that you can instantiate and forget to delete may cause a leak. Primitive data like integers or real hold the information themselves and are always automatically get rid of. Handles like units are referenced by variables, means the variable only points to the object, multiple variables can point to it and you would not want the unit to have killed/copied. Then again, interactive objects like units are an exception, you might not keep them in variables in jass but they may be terminated by the normal engine (like the unit decays after a time after dying) or they are revealed again when running across a jass event (e.g. A Unit acquires an Item-event).

Is what you are saying here, that primitive variables (real, string, boolean, etc.) are automatically removed, and thus don't cause leaks? And that object variables (units, locations, etc.) do? Or am I understanding it incorrectly?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
What I managed to deduce from your post was this: remove/nullify all variables that I won't/can't access later on. Is that the gist?
That is partially true, but not completely.
It is obvious that variables hold data, and thus they use a part of the memory. If you never use them again, this data (and the memory they use) is pointless and is indeed a leak.
However, some types of variables (locations, special effects) are not removed if you only null them, this is because it creates a handle, to witch the variable points (when nulling, the pointer is removed, not the handle, so the handle still leaks). To remove the handle leaks, see below (the JASS-lines).

Strings do leak, but in a different way: strings are being re-used (unlike locations: every time you create a location, even though they both have the exact same coordinates, it creates a handle and thus leaks).
So strings only leak once (if you loop the same message 100 times, it only creates 1 leak).
There's no way to remove string leaks, but they're very insignificant (and again: they're being re-used, that helps a lot).
Integers, reals and booleans do not leak at all.


Removing leaks:

In GUI, you can only remove 1 leaks: special effects.
  • Special Effect - Destroy {effect}
In JASS, you can remove a lot more leaks, here are the common ones:

call DestroyEffect(effect) - removes special effect leaks.
call RemoveLocation(location) - removes location leaks.
call DestroyGroup(group) - removes unit group leaks.
set bj_wantDestroyGroup = true - another way to remove group leaks. This is for when you only use the group once (and it's better than the previous one because you don't need a new variable).
call DestroyForce(force) - removes player group ( = force) leaks.
call RemoveWeatherEffect(weathereffect) - removes weather effect leaks.
call RemoveRect(rect) - removes rect (in GUI called "region") leaks.
call RemoveRegion(region) - removes region (a combination of rects) leaks.

That's all I can think of for now (well, there are also condition, action and trigger leaks I believe, but that's not worth fixing afaik).
 
Level 7
Joined
May 13, 2011
Messages
310
Sweet man, nice explanation. Thanks a lot.

I got a small question though: how does bj_wantDestroyGroup work? I mean, it doesn't specify a group, only true/false.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Sweet man, nice explanation. Thanks a lot.

I got a small question though: how does bj_wantDestroyGroup work? I mean, it doesn't specify a group, only true/false.
Oh, I may not have explained that very carefully indeed ^^

It's something that is usually used in GUI (because GUI uses other, slower, actions to do the same things as JASS).
When "bj_wantDestroyGroup" is set to true, it will call "DestroyGroup" the next time you use a unit group.

  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 1 (Red)) and do (Actions)
    • Loop - Actions
      • Unit - Kill (Picked unit)
This removes the leak, because the "wantDestroyGroup" destroys the next group is finds (no variable required).

  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 1 (Red)) and do (Actions)
    • Loop - Actions
      • Unit - Kill (Picked unit)
  • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 2 (Blue)) and do (Actions)
    • Loop - Actions
      • Unit - Kill (Picked unit)
This still leaks! "wantDestroyGroup" is automatically set to false after finding the first group, so the second unit group leak is not destroyed.
To remove the second leak as well, you can simple set "bj_wantDestroyGroup" to true again (before the second unit group), or use a variable to remove it (but then you need 2 extra actions: setting the variable and destroying it).
 
Level 7
Joined
May 13, 2011
Messages
310
I see, I see. My triggers are definitely leaking then :ogre_hurrhurr:

Thanks for that. So for all other object leaks I should only worry about object variables? Or can I do stuff like call RemoveLocation(lastCreatedLocation) (or however you reference to "last created" stuff in JASS)?
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Unfortunately, there is no "bj_lastCreatedLocation" (that's always the name: bj_lastCreated + variable type as found in JASS).
You've got last created unit/group/effect/timer/..., but no location :p

I would create variables for everything aside from unit groups (set bj_wantDestroyGroup) and special effects (it has a "last created special effect" in GUI as well as JASS).
 
Level 7
Joined
May 13, 2011
Messages
310
Thanks man, I will heed your words and do as you recommend. I'd give you rep but apparently I haven't spread it around enough.

Once again, thanks!
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
Leaks are (basically) variables that are not being used or going to be used and are simply taking up memory, thus causing lag. Is that correct
Although half true (in some real languages you can allocate variables at will), this is impossible in JASS used by WC3. It also can not cause lag as it does not add any net traffic but it can degrade performance if the variables are stored in a structure with some complexity (like python stores them in a hashtable based structure).

Are variables the only things that leak? Do hashtables leak? Do arrays leak?
Anything that causes computer resources to be reserved for a task can leak. Although variables and their array forms can not leak in JASS (as we can not allocate or deallocate them dynamically), hashtables can as they are a separate object. Further more, hashtables can not be deallocated once allocated. There is however a maximum ammount hashtables can leak of 256 hashtables, after which no more can be allocated so no more leaks can occur.

You could technically class poor programming practicies in JASS that do not use variables efficiently as leaking variables, but people generally ignore this for the fact that otherwise it is very difficult to make efficient code and is annoying to make anything quickly.

I have heard that things like Locations and Unit Groups leak. What other kind of variables leak?
Any object that is allocated but not deallocated when no longer required is a leak. Even items can leak in the form of tomes or if killed as they do not automatically get removed. Likewise effects are not deallocated once all apparent visualls finish.

Be aware that units leak permantly. Although you can free up most of the resources used by a unit, it is impossible to fully clean up a unit that is created and thus creating units leak. The method of unit removal has no effect at all on the amount leaked, whether left to be removed by decay or induced by the removal native.

How do I remove leaks? I know of JASS such as RemoveLocation() , but what JASS/GUI functions can I use for each type of leak, and how do I use them (if there is a specific way)?
The natives to remove an object of a certain type usually begin with Remove* or Destroy* where * specifies a name simlar to the type it interacts with. Not all types can be removed (eg caches, strings, hashtables) and not all removals completly clean up leaks (units). Be warned that deallocating a trigger can cause a game crash under certain circumstances (apparently if the trigger is queued to run in the game engine at time of its deallocation).

Does JASS leak more than GUI, vice versa, or doesn't it matter?
WC3 only runs 1 scripting language and that is JASS. GUI compiles to a JASS script when you save the map. Scripting in JASS usually allows more efficient code than using GUI but they both have the same potential to leak.

Any special tips I should know about leaks?
If you do not need some computer resources, try and free them so that other processes/tasks can use them.
 
Level 7
Joined
May 13, 2011
Messages
310
Thanks for all that DSG, it was explained very nicely! I wasn't exactly clear on what to do with leaks, but I think I've got it now.

By the way, about the first question: when I said lag I actually meant a performance lag, not internet lag, maybe I should have stated it more clearly. Obviously the speed of Battle.net depends on your network connection and all those other variables. (In this case real life variables, not WC3 :wink:)
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Any special tips I should know about leaks?

If you want to avoid leaks (Im talking about locations), use coordinates, you can use it even in GUI...make a real variable and get the X and Y of 'something' like GetUnitX and GetUnitY...


Or if you want to create a unit in a certain point in a map, do...

  • custom script: set udg_UNIT = CreateUnit(Player(0), 'hpea', -1560, -1022, 0)
I got the numbers from this...the pointer of your mouse can get the coordinates...
167625-albums4053-picture48069.jpg

 
Level 7
Joined
May 13, 2011
Messages
310
Hm, good idea, before I knew Locations leaked it just looked bothersome to do that but I get it now.
But suppose I want to get the coordinates of something like the centre of a Region or Item? You already said I could use GetUnitX(). Do I use something GetRectCenterX() or what?
 
Level 7
Joined
May 13, 2011
Messages
310
Yeah, I got the "any point" thing.

By the way, I didn't ask how to set an Item at a Rect's centre, I asked how to get the X and Y coordinates of Rects or Items.

But it's cool, I'll just use a JASS reference.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
To get the center...
JASS:
local real x = GetRectCenterX(bj_mapInitialPlayableArea)
local real y = GetRectCenterY(bj_mapInitialPlayableArea)
call BJDebugMsg(R2S(x))
call BJDebugMsg(R2S(y))
//these messages will show the real values

To get the coordinates of item, GetItemX and GetItemY...

To get the coordinate point...use GetSpellTargetX and GetSpellTargetY...

You must Get it first before you can Set it...
 
Status
Not open for further replies.
Top