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

[JASS] Do hashtables have a leak?

Status
Not open for further replies.
Level 4
Joined
Dec 9, 2008
Messages
52
This bit of code runs fine for a minute and then the lag gets progressively worse. Without this trigger the game doesn't lag even after an hour. Any ideas? I realize I'm calling this function a lot and there's a logical mistake in it, but that doesn't affect the fact that it's leaking.

Code:
function checkheight takes nothing returns nothing
    local real last_x = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_x"))
    local real last_y = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_y"))
    local real last_z = LoadReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_z"))
    local location l = GetUnitLoc(GetEnumUnit())
    local real x = GetLocationX(l)
    local real y = GetLocationY(l)
    local real z = GetLocationZ(l)
    local real distance = SquareRoot((x-last_x) * (x-last_x) + (y-last_y) * (y-last_y))
    local real height = z - last_z
    local real slope = AtanBJ(height/distance)
    if slope > 60 then
        call SetUnitPosition(GetEnumUnit(),last_x,last_y)
    else
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_x"),x)
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_y"),y)
        call SaveReal(udg_hash,GetHandleId(GetEnumUnit()),StringHash("last_z"),z)
    endif
    call RemoveLocation(l)
endfunction

function Trig_pumpheight_Actions takes nothing returns nothing
    call ForGroup(udg_allunits, function checkheight)
endfunction

//===========================================================================
function InitTrig_pumpheight takes nothing returns nothing
    set gg_trg_pumpheight = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_pumpheight, 0.02 )
    call TriggerAddAction( gg_trg_pumpheight, function Trig_pumpheight_Actions )
endfunction
 
Level 4
Joined
Dec 9, 2008
Messages
52
Thanks for your response.

I understand that I need to use FlushChildHashtable() or whatever once the data are no longer useful. However, after this trigger runs just once, all of the hashtable keys and values are set and none are going to be added or destroyed. There are like 50 units whose position I keep tracking. I just rewrite their previous position with their existing position.

In other words, I'm rewriting old values and not creating new ones. Memory should not be leaking from this function.

I think I'm missing something.
 
Level 4
Joined
Dec 9, 2008
Messages
52
Thanks for responding again.

I understand I'm calling this function a lot; however, if the game can't handle that it should be an all-or-nothing type of lag. Either it can finish those 2500 calls per tick or it can't.

The type of lag I'm getting is progressively worse, which from my understanding is from leaks. Am I misunderstanding the symptoms and this is really just too much for the game to handle?

BTW, I had set the location to null, but the onset rate of lag was identical so I just took it out.

EDIT: First and second paragraphs are wrong. Third paragraph I was mistaken.
 
Last edited:
Level 4
Joined
Dec 9, 2008
Messages
52
Also, when I reduced either the amount of units or the frequency of trigger execution, the lag onset was roughly proportional to reduction amount.

That is, when I had only half the units it took twice as long for it to lag.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Its called your leaking 50 handle indexes per second.
null the local handle at the end of the trigger to make sure it has no value and the leak should be gone. Its a WC3 bug, whereby handle indexes can not be recycled if they are stored in a variable, and locals obey this rule however at the end of the function are not flushed empty so the handleindex becomes permantly locked and unable to be recycled.

250 handle index leaks per second is major. Yes it should not really cause lag, but the more indexes WC3 uses, the more demanding some opperations become.

I also advise using only 1 load / save opperations per execution which loads an integer corosponding to a index in 2 arrays which stores the value. Array manipulation need well under half the time compaired to hash manipulation, so it is best to avoid it in rapid fire perodic code as much as possible.
 
Level 4
Joined
Dec 9, 2008
Messages
52
Thanks for the answer! It's also good to know about the hash calls versus array calls.

What, exactly, is an example of a handle index in this code?

Ok I feel dumb now. I got home from work and tested it, and I was nulling the location before I removed it. So... yeah..

Thanks to everyone who helped me fix this!
 
Last edited by a moderator:
Status
Not open for further replies.
Top