• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

1.24 Unit leaks

Status
Not open for further replies.
Level 2
Joined
Dec 1, 2008
Messages
7
While reading the forum I came across several posts saying that units always leak because they are not cleaned up properly by RemoveUnit() (since 1.24), but could not find out if that bug still exists.

Was the bug fixed in any of the later 1.24X patches or in 1.25?
If not, are there any clean workarounds for maps that need to spawn very large amounts of units and thus have a high chance of crashing.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
A lot of people reporting leaks do not understand how computer memory works. They work by how big the working set or virtual size of WC3 is (and how it changes) when certain natives are run. This may work for major leaks like groups of all units on the map but most data structures should not alter memory noticably at all meaning that they have an unaccomidated source of error.

Although the leak may be true, it all comes down to how they tested for it and weather it was comprehensive enough (analysing assembly etc).

Leaks like locations or handle IDs can be detected and proved very easilly by the adresses never getting recycled (GetHandleId). Leaks with dealocating stuff however is not that easy to prove as it all comes down to how WC3 interally handles memory and when does memeory get recycled.
 
I think it still exists. However, it only happens after some time of playing. (eg: it won't crash just because you have 300 units in the beginning of the map) If it does become a problem, the things to help are:
  • Save/Load Systems - By doing this, you can essentially allow people to save/reload when it gets too laggy. Save/load systems result in a fresh new map, so it should work fine for a while again.
  • Unit Recycling - Unit recycling helps in things like tower defences and tower/footman wars the most. If you are doing it for your own map, you need to understand how the process works a bit. In an ORPG, it can be pretty hard. In something like an AoS or tower wars which usually spawn the same units repeatedly, it is relatively easy. (although, not always even then) The key to unit recycling is to reuse units that have died rather than creating new ones. I have made a system that works like that for creeps, but I never released it and it has an incomplete feature.
  • Dummy Recycling - Same thing as unit recycling, but there actually exists some systems for dummy recycling. You know how spells often have some dummy unit for effects and things like that? Then you apply timed life. However, some systems allow you to reuse dummies for other things, so you won't constantly create more and more dummies. If your map has several triggered spells, either GUI or JASS, this can make a decent difference.

Sometimes, there is nothing you can do. But generally, just make good practices and be wise about creating units. ;) However, there are several maps that will successfully run for a while and still have plenty of units, so this doesn't necessarily mean that your map has to be bland. :ogre_haosis:
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
The leak exists and was in fact introduced in 1.24. I can attest to that as I play many maps like footmen wars ;D. 1.23 was no crashes, 1.24 was constant crashes on the exact same map. Conclusion, units now leak ^_^. Will Blizzard ever fix the leak they introduced? Dunno, probably not ^)^.

Too bad crashes can be cause by other things, like stupid use of hashtable. Again that is no evidence for units leaking as leaks do not nescescarilly mean crashes. Infact the only time a leak will cause a crash is if it hits some sort of limit which can be in the hundreds of thousands.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Exact same map, no code change, no crash in 1.23 from 2 games of playing, crash in 1.24 with 1.5 games of playing. I could even play a map on wc3 50x in a row w/o crashing in 1.23, but I can't even get through 2 on 1.24 w/o a crit error. Again, exact same map, no code change.

The crashes only occurred on maps with large numbers of units (tower wars, footmen wars, etc). These maps that worked so perfectly before started crashing halfway into the next game if not sooner >.>. Restarting wc3 between every single game fixed the problem, but that tells me that wc3 is leaking ;D.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
And that proves anything? I am sure they changed a great deal of things.
Remember how logic works. Just because leaks can cause crashes does not mean all crashes are caused by leaks.

Thus the only concrete proof you can get is if you prove it is not caused by other changes in the patch or if you actually find the change which caused it and what is triggering the crash.

Back before the 1.20 patch, there was a common crash caused by units walking into areas they should not (you would see a unit suddenly walk into a wall or something retarded and then the game fataled). That seems fixed fortunatly. Additionally there is a crash related to trigger destruction which no one understands fully which may have been aplified by trigger modifications.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Actually, that could be the case as I have run tests in wc3 just creating/removing sets of units. As I increased a count, the handle table would increase (visible in memory). Handle table is almost similar to a dynamic array (continues to double in size o-o). What's odd though is that I would create and remove the exact same unit and the memory would still go up (doubling in size in the handle table etc as if the handle table were actually increasing the total handle count). It was a simple RemoveUnit(CreateUnit(...)). Warcraft 3 never crashed, but it sure had a lot of memory allocated by the time I closed it. Perhaps the units do have permanent leaks in the handle table, and when mixed with some other factor, will cause a critical error.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
->Dr Super Good

Bribe said that setting a unit's explode flag to true and then killing it would properly clean it. That's his word, not mine, but he said that he did test it and memory didn't go up. He also said that it did go up with the same test using RemoveUnit. Another thing is that decay probably wouldn't work so well because of all of the problems with the maps that have lots of units in them.
 
JASS:
call SetUnitExploded(whichUnit,true)
call KillUnit(whichUnit)

Or, in GUI, simply:
  • Unit - Make (Triggering unit) Explode on death
SetUnitExploded(whichUnit,true) should skip corpse decay and immediately go to the game engine removal. Supplying false will have the corpse/decaying exist if I recall correctly. I guess now it can be used as a neat trick to save some memory.

However, I never tested it myself either. ;P
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
What I always found odd is that when using RemoveUnit, that unit would not immediately charge off its supply cost, it's like the unit would still influence gameplay, not being completly destroyed. A general check to pick units in a list, see if they are alive, is doubtful as CreateUnit and KillUnit adjust the value instantly and should be cheaper.

Maybe Blizzard will fix it someday, but in the process they would probably create new bugs.
 
Level 2
Joined
Dec 1, 2008
Messages
7
Has anyone tested using SetUnitExploaded(), and if it does work, is the unit removal done by KillUnit() the same as the unit actually being killed from damage.

If so then would replacing CreateUnit() with a function like the one below be enough to prevent leaks in maps where most units are created by triggers (AoS, Hero Defense, Footman)

JASS:
function CreateUnitEx takes ...... returns unit
local unit u 
set u = CreateUnit(.......)
call SetUnitExploaded(u)
return u // leaks u
endfunction
Though the local can't be nulled before return causing a handle leak so I guess it should either be inlined by hand or through a textmacro if it does actually work.
 
Status
Not open for further replies.
Top