• 🏆 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!

How bad are leaks??

Status
Not open for further replies.
Level 32
Joined
Apr 2, 2013
Messages
3,954
Level 23
Joined
Apr 16, 2012
Messages
4,041
a lot, just open the game in window mode, and open task manager, and check the memory rising, if it goes up steadily you are in deep trouble.

Generally, you could have 10000 leaks but if every one of them only happens once per the whole map, thats not even big deal(unless you leak super expensive stuff).

If you have single leak, for instance location, or group, and it is placed inside "Every 0.03 seconds" the map may very well become unplayable(lag to oblivion) after maybe half hour or hour
 
Level 7
Joined
Aug 15, 2012
Messages
318
a lot, just open the game in window mode, and open task manager, and check the memory rising, if it goes up steadily you are in deep trouble.

Generally, you could have 10000 leaks but if every one of them only happens once per the whole map, thats not even big deal(unless you leak super expensive stuff).

If you have single leak, for instance location, or group, and it is placed inside "Every 0.03 seconds" the map may very well become unplayable(lag to oblivion) after maybe half hour or hour

O thats what happened everytime I played cot ORPG lol I swear there was ALOT of leaks in that shit. sorry for offtopic
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
@Edo
He is correct if the spells is the only thing that leaks. Let's say there is a location leak and a special effect leak in the each spell. That's 8 bytes per spell cast. So after 100 spells have been casts 1 kb of memory has been used.

Provided it actually was 4 bytes, it MIGHT have been gui globals that took 4 bytes if they wasn't nulled. I have a feeling that might be the case.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
If you leak a location and special effect, you are probably leaking more like 50 to maybe even like 100 bytes per leak(location is for sure at least 12 bytes + 4 bytes for ref count, depending on how the animation is stored inside the effect, it could go upwards to 100 bytes, but it has to store its position, who its hooked to, the state(as in, what frame am I currently on) etc)
 
Level 13
Joined
Oct 18, 2013
Messages
691
Why risk it? Just fix the leaks in your spells. It's pretty simple, and then you don't have to worry about leaks c:
 
Level 19
Joined
Jul 2, 2011
Messages
2,162
do too many units leak? or the creation of units?

I've leak fixed every aspect of my game, but when there are too many units the game often crashes.

like there is this one monster that dies and turns into 2 monsters, those 2 die and turn into 4...8...16............48

why would that crash the game?
 
Level 11
Joined
Jun 26, 2014
Messages
497
Is there anyway for me to test if the map will lag except playing on it? I have tested it with 6ppl (fullhouse) and there was no lag at all. And some of the laggiest heroes were chosen.

Edit: Trust me my computer isn't anywhere near a powerful computer. I can't play Dota2 cuz of lag(40 and below fps).
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
You could post the triggers of the spells and have the tech guys here manually check them for leaks.

@edo & chaosy: bite sized! Like those corned-beef cut potatoes :D
 
Level 11
Joined
Jun 26, 2014
Messages
497
You could post the triggers of the spells and have the tech guys here manually check them for leaks.

@edo & chaosy: bite sized! Like those corned-beef cut potatoes :D


  • Spell Sword Charge
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to 3Arcane Charge
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of 3Arcane Charge for (Triggering unit)) Equal to 1
        • Then - Actions
          • Set SSC_Caster = (Triggering unit)
          • Set Target_Spell_Sword_Charge = (Target unit of ability being cast)
          • Animation - Play (Triggering unit)'s walk animation
          • Unit - Turn collision for SSC_Caster Off
          • Trigger - Turn on Spell Sword Charge Loop <gen>
          • Wait until ((Distance between (Position of SSC_Caster) and (Position of Target_Spell_Sword_Charge)) Less than or equal to 180.00), checking every 0.10 seconds
          • Trigger - Turn off Spell Sword Charge Loop <gen>
          • Unit - Turn collision for SSC_Caster On
          • Animation - Play (Triggering unit)'s attack animation
          • Set unit_group_spell_charge = (Units within 250.00 of (Position of SSC_Caster) matching (((Matching unit) belongs to an enemy of (Owner of SSC_Caster)) Equal to True))
          • Special Effect - Create a special effect attached to the origin of SSC_Caster using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
          • Special Effect - Destroy (Last created special effect)
          • Unit Group - Pick every unit in unit_group_spell_charge and do (Actions)
            • Loop - Actions
              • Unit - Cause SSC_Caster to damage (Picked unit), dealing (25.00 + (2.00 x (Real((Agility of SSC_Caster (Include bonuses)))))) damage of attack type Hero and damage type Normal
              • Custom script: call DestroyGroup(udg_unit_group_spell_charge)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of 3Arcane Charge for (Triggering unit)) Equal to 2
        • Then - Actions
          • Set SSC_Caster = (Triggering unit)
          • Set Target_Spell_Sword_Charge = (Target unit of ability being cast)
          • Animation - Play (Triggering unit)'s walk animation
          • Unit - Turn collision for SSC_Caster Off
          • Trigger - Turn on Spell Sword Charge Loop <gen>
          • Wait until ((Distance between (Position of SSC_Caster) and (Position of Target_Spell_Sword_Charge)) Less than or equal to 180.00), checking every 0.10 seconds
          • Trigger - Turn off Spell Sword Charge Loop <gen>
          • Unit - Turn collision for SSC_Caster On
          • Animation - Play (Triggering unit)'s attack animation
          • Set unit_group_spell_charge = (Units within 250.00 of (Position of SSC_Caster) matching (((Matching unit) belongs to an enemy of (Owner of SSC_Caster)) Equal to True))
          • Special Effect - Create a special effect attached to the origin of SSC_Caster using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
          • Special Effect - Destroy (Last created special effect)
          • Unit Group - Pick every unit in unit_group_spell_charge and do (Actions)
            • Loop - Actions
              • Unit - Cause SSC_Caster to damage (Picked unit), dealing (50.00 + (2.00 x (Real((Agility of SSC_Caster (Include bonuses)))))) damage of attack type Hero and damage type Normal
              • Custom script: call DestroyGroup(udg_unit_group_spell_charge)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of 3Arcane Charge for (Triggering unit)) Equal to 3
        • Then - Actions
          • Set SSC_Caster = (Triggering unit)
          • Set Target_Spell_Sword_Charge = (Target unit of ability being cast)
          • Animation - Play (Triggering unit)'s walk animation
          • Unit - Turn collision for SSC_Caster Off
          • Trigger - Turn on Spell Sword Charge Loop <gen>
          • Wait until ((Distance between (Position of SSC_Caster) and (Position of Target_Spell_Sword_Charge)) Less than or equal to 180.00), checking every 0.10 seconds
          • Trigger - Turn off Spell Sword Charge Loop <gen>
          • Unit - Turn collision for SSC_Caster On
          • Animation - Play (Triggering unit)'s attack animation
          • Set unit_group_spell_charge = (Units within 250.00 of (Position of SSC_Caster) matching (((Matching unit) belongs to an enemy of (Owner of SSC_Caster)) Equal to True))
          • Special Effect - Create a special effect attached to the origin of SSC_Caster using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
          • Special Effect - Destroy (Last created special effect)
          • Unit Group - Pick every unit in unit_group_spell_charge and do (Actions)
            • Loop - Actions
              • Unit - Cause SSC_Caster to damage (Picked unit), dealing (75.00 + (2.00 x (Real((Agility of SSC_Caster (Include bonuses)))))) damage of attack type Hero and damage type Normal
              • Custom script: call DestroyGroup(udg_unit_group_spell_charge)
        • Else - Actions
  • Spell Sword Charge Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Set temp_point_Spell_Sword_Charge[1] = (Position of SSC_Caster)
      • Set temp_point_Spell_Sword_Charge[2] = (temp_point_Spell_Sword_Charge[1] offset by 30.00 towards (Facing of SSC_Caster) degrees)
      • Unit - Move SSC_Caster instantly to temp_point_Spell_Sword_Charge[2]
      • Unit - Make SSC_Caster face Target_Spell_Sword_Charge over 0.01 seconds
      • Custom script: call RemoveLocation(udg_temp_point_Spell_Sword_Charge[1])
      • Custom script: call RemoveLocation(udg_temp_point_Spell_Sword_Charge[2])
I think this is the spell that leaks the most. This is my first try making any spell of this kind so I know the triggers look awful.

Edit: If I cast it let's say 100+ times will the game start to lag?
 
As a rule of thumb: leaks more or less only matter in periodic triggers or on long game sessions.

If the typical session is only 30 minutes, you will be fine.

However, there is no harm in fixing leaks and it actually makes you write cleaner code if you do (as it will most likely fix some bad habits in the process).
 
Level 5
Joined
Aug 19, 2015
Messages
68
i think you just need to add a "call DestroyGroup(udg_unit_group_spell_charge)" each
to fix the 3 unitgroup leaks.
maybe you also need to null them and the effects.
on my map i even did it with local vars because somebody said that's better
 
Level 11
Joined
Jun 26, 2014
Messages
497
Really the leaks you definitely want to mitigate are the ones that occur if you are leaking a point when you run a trigger every 0.01-0.03 seconds or even every 30 seconds.

That's what I did.
i think you just need to add a "call DestroyGroup(udg_unit_group_spell_charge)" each
to fix the 3 unitgroup leaks.
maybe you also need to null them and the effects.
on my map i even did it with local vars because somebody said that's better

Look at the trigger closely... you can see that I have already done that.
 
Leaks are really bad and unnecessary, even outside a looping trigger. I have this saying that ~ Just because your code is working, doesn't it mean that you code it correctly. You should always ALWAYS strife to make your code as efficient as possible, not only in wc3 put in every programming language. In your spell for example, you should turn the looping trigger off when you don't use it because it only waste processing that could have been spend on something more important.

As a second note, it is recommended that you study this tutorial: Making MUI spells. You may think that it is not a must because you will probably never cast 2 looping spells of the same type in your map, well that is not true. If you want to add a mod where more than 1 of the same hero type can be played then the looping spells will get buggy when 2 of the same looping spells are cast at once. The point is that you sould try to make your code flexible so you can easily add updates without adjusting existing code.
 
Level 11
Joined
Jun 26, 2014
Messages
497
Leaks are really bad and unnecessary, even outside a looping trigger. I have this saying that ~ Just because your code is working, doesn't it mean that you code it correctly. You should always ALWAYS strife to make your code as efficient as possible, not only in wc3 put in every programming language. In your spell for example, you should turn the looping trigger off when you don't use it because it only waste processing that could have been spend on something more important.

As a second note, it is recommended that you study this tutorial: Making MUI spells. You may think that it is not a must because you will probably never cast 2 looping spells of the same type in your map, well that is not true. If you want to add a mod where more than 1 of the same hero type can be played then the looping spells will get buggy when 2 of the same looping spells are cast at once. The point is that you sould try to make your code flexible so you can easily add updates without adjusting existing code.

I know but the map I am working on is quite ahead in it's progress so I'd have to remake everything. I know that if a code works it doesn't mean it's good and that I should always strife for the best but right now...I will just continue on with my map and if any spells/triggers make problems I will fix the leak.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
As I said, it might have been unnulled GUI variables that was 4 bytes, I don't really remember.
That still would be more than 4 bytes as the handle id management structures are likely at least 12. 4 bytes for the id, 4 bytes for the reference counter and 4 bytes for a pointer to next element ( to allow them to be more easily recycled). You can then count a few bytes for alignment or memory management overhead still.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Theres really no need for pointer to next element, so they could be 8 bytes
Yes but then you have 8-12 byte linked list structures to hold recycled handle ids. Would make allocated handle id structures smaller but increase the overhead of recycled handle id values.

If they are C++ objects using abstraction (which they might to deal with various kinds of handle such as floating text, players etc) they might have a 4 byte pointer to the class method table.

4+4+4 is perfectly aligned so no alignment payment
One cannot say that. Compilers are allowed to apply extra padding as they find appropriate. Additionally the allocation algorithm might constrain the packing and also has overhead.

This is for the handle id structure alone. Any object the handle id structure links will also leak and can be huge. For example a group containing all units on the map (a popular GUI leak) can be well over a kilobyte in size.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
The memory still has to be word aligned, and since 4 + 4 + 4 is perfectly aligned, there is no need to add padding into this. Even if one of these was character, it would still be the same alignment.
It might be aligned to fit evenly inside a page or to fit inside processor cache lines. It still might need a virtual table pointer as well which is an extra 4. The reality is that you cannot say what alignment such a structure would take if you made it. Sure you can say what alignment the structure is by reverse engineering but that is different.

You will find some list of all handles somewhere. This is either in the form of a doubly linked list member of the handle id object or in the form or a separate list. Both add extra memory overhead. This would be needed to enumerate all handles when a session ends so that the memory can be freed for the next session. It is clear WC3 does this by you leaving a session that leaked very badly and it taking several seconds (10+) to get back to the menu as opposed to the usual near instantaneous (1-2 at most).

The main problem with leaks is not so much memory related (memory inflation over a decade killed that issue) but rather complexity leaks (once fast operations start to take forever to complete). Strings are the best example of this since unique strings always leak (no destructor, no recycling) and after enough have leaked creating new strings can take several frames of execution time.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
Ref count needing virtual table pointer? what kind of ref counter needs to be polymorphic.

To my knowledge visual studio aligns to word, not to cache size(aligning 12 bytes to cache line would be ridiculous), and they compiled Warcraft with visual studio, so there is reasonable assumption that if it stores integer + pointer, it will be 4+4 hence 8 bytes(if there is pointer to next, it will be 12).

You also dont say unit takes additional 4 bytes just because it may be placed inside group, so the linked list isnt really a problem.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Ref count needing virtual table pointer? what kind of ref counter needs to be polymorphic.
Handle IDs are more than a reference counter though. They at least contain an object pointer (what the handle references), a reference counter and possibly the handle id number itself. They might also contain 1-2 pointers to other handle ID structures for freeing purposes once the game session ends. The virtual table might be needed so that various kinds of hand ids can be dereferenced (based on the handle type).

Handle ids have a strange number range so could also be arranged in a binary search tree to enable log(n) dereferencing without needing to allocate massive continuous arrays. This would explain why performance degrades as more and more of them leak since dereferencing a handle id takes longer and longer, although scaling well.
 
Level 6
Joined
Jan 4, 2014
Messages
227
My map used to crash even in 1 vs 1 matches, so i started clearing the leaks using GUI, but the problem was ... i got about 120 spells to recode :/

I advice you to start clearing the leaks now as you have few spells.

Some thing much much much more better will be to use JASS since local variables does not leak.
 
Level 6
Joined
Jan 4, 2014
Messages
227
@Bribe, you mean if i store a location in a local variable, the location remains even if the function end and the local variable is destroyed ?
 
Status
Not open for further replies.
Top