HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

To be sure (Memory Leaks)

08-18-2005, 11:37 AM#1
Thunder_Eye
I havent had any problems with Memory Leaks before and not now either by the way. But why not remove them anyway?

So.. I'm gonna use custom scripts to remove them cause I'm not so familiar with JASS.

Now, my problem is I cant find what to put in in the custom script. I know:
call RemoveLocation( udg_tempPoint )

But I want to clean up "all" my memory leaks.

I need to clean up:
UnitGroups
Reals
Players
Items
Unit-Types
Integers
Item-Types
Strings
Booleans
Sounds

The best would be if someone could send all things that leak.

Quote:
Spawn Corpses
Events
Unit - A unit Dies
Conditions
Actions
Set tempPlayer = (Owner of (Dying unit))
Set tempPoint = (Position of (Dying unit))
Set tempReal = (Facing of (Dying unit))
Set tempUnit = (Dying unit)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Unit-type of tempUnit) Equal to Wolf
Then - Actions
Set tempUnitType = Dead Wolf
Unit - Create 1 tempUnitType for tempPlayer at tempPoint facing tempReal degrees
Set Loot = (Random integer number between 1 and 30)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Loot Less than or equal to 3
Then - Actions
Do nothing
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Loot Greater than or equal to 4) and (Loot Less than or equal to 13)
Then - Actions
Else - Actions
Unit - Remove tempUnit from the game
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Unit-type of tempUnit) Equal to Pygmy Troll) or ((Unit-type of tempUnit) Equal to )
Then - Actions
Set tempUnitType = Dead Pygmy Troll
Unit - Create 1 tempUnitType for tempPlayer at tempPoint facing tempReal degrees
Set Loot = (Random integer number between 1 and 2)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Loot Equal to 1
Then - Actions
Do nothing
Else - Actions
Unit - Remove tempUnit from the game
Else - Actions

Custom script: call RemoveLocation( udg_tempPoint )

Can anyone find any leaks? (exept Im gonna destroy those variables when I get the script for it)

btw. Is
call DestroyTrigger(GetTriggeringTrigger())
correct spelled?
08-18-2005, 10:53 PM#2
Elven Ronin
Points and unit groups tend to be the biggest causes of leaks, and you've already got the point purger. I'm pretty sure that unit group variable can be destroyed using GUI, there's a unit group - clear action.

I don't know the ones for the rest of the variables, I'm sure someone better with JASS or memory leaks could help you there.

And about the destroy triggering trigger, I'm pretty sure that's the way its spelled.
08-18-2005, 11:16 PM#3
Anitarf
Hmm, this should belong more in the trigger section but anyway...

Lets start with a brief overwiev of how leaks happen, or more precisely, how handle object leaks happen. These memory leaks are what we deal with the most, there are others, like string leaks (which can't be prevented at all, but are usually insignificant), and the problem with local handle variables (which is a part of handle object leaks but won't be covered here for the sake of keeping it short and simple, because local variables are only used in JASS anyway). By the way, custom scripts are JASS.

Handles are game objects... units, doodads, destructibles, items, special effects and also regions, locations, unit groups, player groups... all this stuff. Things that are not handles are integers, reals, booleans; these are just numbers. They are stored in their variables and are erased the moment the variable is set to a new value.

Handle variables, on the other hand, are pointers: they only contain a number that points to where in the game's memory the object is located. Handle objects exist independant of variables. They can exist without any variables pointing to them, in that case, they can't be removed from memory because there's no way to tell the functions that are used to remove them where in the memory they are. Such unreferenced handles are only cleared from memory at the end of a game by a garbage collector (the source of end game delay), but while the game lasts, they accumulate and can cause performance issues.

Now, there are plenty of functions that create handles. Center of region, random point in region, position of unit, target point of ability being cast... and many others create a location object, which is usually used to create units at, or special effects, or for measuring distances between points... Units in region, units owned by player, units in range,... all these functions give you a Unit Group. Then there are player groups and all other things already mentioned and more.

You may only need these objects for a moment, but the game can't know that, so they don't just go away by themselves when you no longer need them. The location doesn't just dissapear once a unit is created at it. We must use special functions to dispose of the handles we only create temporarily and don't need them to last. The most commonly used are:
RemoveLocation()
DestroyGroup()
DestroyForce()
...


There are more, but these are all an apprentice triggerer really needs to know. There is a GUI action for removing a special effect, so we don't need to know the JASS function for that, units are removed from memory automatically once their corpses decay, and anything else is usually too rare to care about. If we are practical, the only thing we really need to care about are temporary handles that are created dynamically and rapidly, in triggers that run often or loop a lot. So what if a cinematic trigger that runs only once leaks a few locations? It's the tens of thousands of locations or unit groups that can leak on a fast periodic trigger that matter.

As has already been mentioned, to remove a temporary handle that has served it's purpose, we need to know where it is, we need to have a variable pointing to it. The only way to do that is to point a variable to it when we create it. For that, we first need some variables that we'll use for this purpose, in my examples I'll name them tempPoint and tempGroup. They are global variables that you define in the variable editor, and because of that they get the "udg_" prefix in JASS scripts.

Now, let's say we want to create a footman at the center of playable map area. If we didn't care about memory leaks, we would do it like this:

Unit - Create 1 Footman for (Player 1 - Red) at (center of (playable map area)) facing 0.00 degrees

However, the (center of (playable map area)) creates a location object at which the footman is then created, and this location then "leaks" because we can't remove it, because there's no way to know where in memory it is. We avoid this leak like this:

Set tempPoint = (center of (playable map area))
Unit - Create 1 Footman for (Player 1 - Red) at tempPoint facing 0.00 degrees
Custom script: call RemoveLocation( udg_tempPoint )


and similarly for everything else, let's say we want to kill all units in a region:
Set tempGroup = units in TheUnholyRegionOfVanillaFlavouredDoom <gen>
Unit group - pick every unit in tempGroup and do: Kill (picked unit)
Custom script: call DestroyGroup( udg_tempGroup )


That is about it concerning the basics of memory leaks. Remember not to worry about every petty detail, if you have an old map which you want to fix a bit, just clear the most critical special effect, unit group and location leaks and any noticeable problems with lag will be solved. On future maps, you can afford to be a bit more precise and thourough in hunting memory leaks.

One last note, it is said that destroying triggers after you no longer need them can be quite effective performance-wise, especially with long initialization triggers that run once and are then not used again. To do that, just put the following line at the end of the trigger (yes, you spelled it correctly):

call DestroyTrigger(GetTriggeringTrigger())


edit: hmmm... got kind of long... should have just posted a link to a memory leak tutorial instead of writing my own :)
08-19-2005, 12:30 PM#4
Zoxc
Quote:
Hmm, this should belong more in the trigger section but anyway...

Hmm, this should belong more in the turoials section but anyway
08-20-2005, 12:40 PM#5
Thunder_Eye
Well Ive already read that tutorial so I knew all that ^^
Well thnx anyway, I know its just unnecessary to remove every little leak, but why not do It anyway? It won't hurt the map or wont it?
And yes, I know custom scripts is JASS.

(Sry didnt think of posting it in the trigger section)
08-20-2005, 02:42 PM#6
Anitarf
Well, you did say this:
Quote:
Originally Posted by Thunder_Eye
So.. I'm gonna use custom scripts to remove them cause I'm not so familiar with JASS.
And this:
Quote:
I need to clean up:
UnitGroups
Reals
Players
Items
Unit-Types
Integers
Item-Types

Strings
Booleans
Sounds
So I thought a more thourough explanation was in order. Oh, I think I forgot to mention, Unit-types and Item-types are integers as well.
08-20-2005, 03:07 PM#7
Thunder_Eye
Quote:
So.. I'm gonna use custom scripts to remove them cause I'm not so familiar with JASS.

Well I meant that I dont use JASS, I use GUI, so I'm using custom scripts which actually is JASS to remove the leaks.

And I still didnt get my problem solved,
I need all the "call blablabla.."
for all those things I wrote up.
Quote:
UnitGroups
Reals
Players
Items
Unit-Types
Integers
Item-Types
Strings
Booleans
Sounds

And can I just "Unit Group - Clear (last creadted unit group)"
after Ive created an unit?
08-20-2005, 11:39 PM#8
Anitarf
Quote:
Originally Posted by Thunder_Eye
And I still didnt get my problem solved,
I need all the "call blablabla.."
for all those things I wrote up.
Umm, no, that's what I've been trying to say, you don't need them for all, integers (also including unit types, item types, I think players as well...), reals and booleans don't leak at all. Strings leak and that can't be fixed, but a string leaks only the first time you use it, so it's not that bad (unless you massively generate unique strings). Some objects like Unit or Item have a GUI action for removal, so the only JASS scripts you really need are the ones I already listed in the mini tutorial.

Quote:
And can I just "Unit Group - Clear (last creadted unit group)"
after Ive created an unit?
No, you need to use DestroyGroup(). Clear group action only empties the group, but the group as an object remains in memory.
08-21-2005, 12:23 PM#9
Thunder_Eye
call DestroyGroup() Lastcreatedgroup) ?
or?

btw how do I set an integer to null? just zero?
08-30-2005, 02:02 PM#10
Thunder_Eye
*bump*
08-30-2005, 03:15 PM#11
Anitarf
Well, you can just find it out by yourself. Create a test GUI trigger, use "last created unit group" in it somewhere, and convert it to JASS. That's the method I use when searching for a JASS function (unless I know approximately what it's name is, in that case I just search it up in the JASS editor)
08-31-2005, 12:42 PM#12
Thunder_Eye
Well I used
Set tempGroup = last created group
Call DestroyGroup blablabla