[highlight]Memory Leak Tutorial
By - Rad[/highlight]
What is a Memory Leak?
A memory leak is a small bit of information that is not removed after it is used. Converting anything to a non-official variable can cause a memory leak. Point leaks are using center/random points in memory leaks. Group leaks are when you use a unit, player, or destructible GROUP function (Without variables for the group). Region leaks are whenever you convert a 'point with size' or an area, that is not already a variable or preset, to a region.
Symptoms of a Memory Leak:
• Server Splits .....Server Splits happen whenever alot of memory leaks are detected, they can be very random or always happen at the same time. They can range from everyone except you disconnecting, to having a few players disconnect. If you can find out if the disconnected players are still in the game together then that is solid proof of a server split.
• Heavy Lag .....If your map starts lagging, usually over time, first check to see if something wrong with a trigger. Say you spawn one skeleton every second of the game, it wont lag for awhile but if you dont kill them off it will. A good way to test is have a -killall trigger to check if they are simply overspawning. If this doesnt help, its probrably a memory leak.
• Random Disconnections .....First make sure they are not just leaving, secondly if everyone except you leaves at once, it can either be you randomly disconnecting or a server split. As I said its nice to stay in contact with those who disconnect just to check.
• Slow Performance .....If its not exactly laggy, but is running unusually slow... ask the other people in your game if it seems slow. As long as there isnt a problem spawning or something that can effect your video/sound card to create lag its possible that its from a memory leak.
• Triggered-Spell Lag .....Not only for spells, but any trigger that has alot of possible memory leaks (List below). If it happens when this fires, and your sure of it, use this tutorial to get rid of as many as possible!
Types of Memory Leaks:
- Points: These are the most dangerous when making spells and movement systems with keyboard. Whenever you use the position of an object or a point of a region (Whether it be random or center), and even coordinates, they create a memory leak.
- Groups: Also a common leak, whenever you use "Unit-Group - Pick every unit..." (Also Player and Destructible etc) and you do not use a variable as the group, it will leak.
- Regions: Converting a point with a size to a region, or anything that creates an 'area' without using a region (or preset) will create a memory leak.
- Special Effects: If you do not remove a special effect (Done through a trigger, spells do not leak) it will leak. Even if the spell is finished, the data is still there.
- Strings: Strings are very minor, as they are reused. Once you use "Hi" as a string, every time you use "Hi" it uses the same data, it will not leak... but if you display random messeges (Tips that are preset are fine) it might add up, but probrably not...
Restoring the Memory:
Points: The easiest way to remove a point leak is by using a universal point variable. As long as there are no waits which seperate the declaring of the variable to the use of the variable you only need one variable. If you do use a wait you need a seperate global - If not another trigger may remove its data before it is used.
Leak: Unit - Create 1 footman at (Center of (Region A)) for Neutral passive facing default building degrees Fix: Set Point = (Center of (Region A))
Unit - Create 1 footman at (Point) for Neutral Passive facing default building degrees
Custom Script: call RemoveLocation(udg_Point)
Groups: These are fairly easy to remove, so long as they do not use waits as well. It was suggested to only use waits in integer loops by a few people higher than me.
Leak: Unit Group - Pick every unit in (Units owned by (Player 1)) and do (Unit - Kill (Picked unit)) Fix: Custom Script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units owned by (Player 1)) and do (Unit - Kill (Picked unit)) NOTE: To remove player group leaks, replace "Group" with "Force".
Fix 2:More efficient set UnitGroup = (Units owned by (Player 1))
Unit Group - Pick every unit in UnitGroup and do (Unit - Kill (Picked unit))
Custom Script: call DestroyGroup(udg_UnitGroup)
Regions are usually very minor leaks, unless you customize your spells like War Stomp they shouldnt be a problem. You should only need one variable for these, as they are not as needed to store.
Leak: Unit - Cause (Casting unit) to damage ((Point) with size 500, 500) dealing 500 damage using attack type Normal and damage type Normal Fix: Set (Region) = (Point) with size 500,500
Unit - Cause (Casting unit) to damage ((Point) with size 500, 500) dealing 500 damage using attack type Normal and damage type Normal
Custom Script: call RemoveRect(udg_Region) NOTE: Point would be a variable as this would leak both a point and a region (Like most region leaks)
These are easy to fix, just destroy the effect with the GUI function "Destroy Effect", you may need a variable for this. It will still display its death animation, if it has none it will usually last roughly 5 seconds.
Leak: Special effect - Create special effect at (Point) using (Units\Human\Footman\Footman.mdx) Fix: Special effect - Create special effect at (Point) using (Units\Human\Footman\Footman.mdx)
Set (Footman Effect) = (Last Created Special Effect)
Wait 5 seconds
Special effect - Destroy (Footman Effect) NOTE: If your effect shouldnt disappear, sacrifice the memory leak... just dont use to many!
You cannot do anything about string variables (To my knowledge), if you can I'm sorry I do not have the answer.
.....How do variables help?
Using a variable to store a piece of information is the only way to call upon that information in order to remove it. Sometimes they are automatically stored, example the (Last created...) function will store the information, and you do not need a variable. You still need to remove the (Last created...) after use, though.
.....How do you use the function tags?
Most, if not all of the memory leaks have a different function tag. They all basically use [highlight]call Remove"Function"(udg_Your_Variable)[/highlight] (Also [highlight]call Destroy"Function"(udg_Your_Variable)[/highlight] and with this, you can find a JASS tool that has a list of function names and find out how to remove them yourself!
.....What are some guidelines to reducing memory leaks?
Memory leaks are most common when using periodic events, especially small ones such as (Time - Every .01 seconds of the game). Keep in mind using such a small value means that your FPS is higher than 100 with that event, most peoples arent... if they are they would hardly notice if you used (Time - Every .05 seconds of the game). It might not seem much different, but .01 happens 5 times more than .05, and you cant tell the difference anyways!
Also, using groups (mainly unit groups) are common memory leak generators. Theres a solution above, of course.
.....How do I check if my triggers leak?
If your trigger uses a periodic event under 5.00 seconds, then you need to check for any of the common leaks (Listed above). Also check ones with any group or integer loops. Spells are also very common, mainly for leaking points... so double check those too. Its a good idea to use the Object Manager (F11) to find where functions loop or you use unit/player groups.