Leaking but don't know why

Status
Not open for further replies.
Can't find the leak (probably something new)

JASS:
function EnumStandardFilter takes nothing returns boolean
    set udg_ue = GetFilterUnit()
    return not(IsUnitType(udg_ue,UNIT_TYPE_MECHANICAL)or IsUnitType(udg_ue,UNIT_TYPE_STRUCTURE)or IsUnitType(udg_ue,UNIT_TYPE_DEAD)or IsUnitType(udg_ue,UNIT_TYPE_FLYING)or IsUnitType(udg_ue,UNIT_TYPE_MAGIC_IMMUNE)) and IsUnitEnemy(udg_ue,udg_p)
endfunction

function GroupEnumStandard takes group g, unit u, real x, real y, real r returns nothing
    local boolexpr be = Condition(function EnumStandardFilter)
    set udg_p = GetOwningPlayer(u)
    call GroupEnumUnitsInRange(g, x, y, r, be)
    set be = null
endfunction

  • Execute
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set i2 = 0
      • Custom script: loop
      • Custom script: exitwhen udg_i2 > 2000
      • Custom script: call GroupEnumStandard(udg_g, udg_u, 0, 0, 500)
      • Set i2 = (i2 + 1)
      • Custom script: endloop
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • i Less than 1000
        • Then - Actions
          • Set i = (i + 1)
          • Trigger - Run (This trigger) (ignoring conditions)
        • Else - Actions
          • Game - Display to (All players) the text: rdy
every time I press "Esc" WC3 allocates one more MB of RAM

edit: the trigger really should run 2 million times else I can't measure the leak cause it is small

please help me find the leak

Note:
JASS:
call DestroyBoolExpr(be)
made this trigger leak like 10 MB per second

edit2: similar ammount of leak:
JASS:
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, r, be)
call DestroyGroup(g)
set g = null
(of cause this destroys the group so I can't use it any longer but it was just to test that it leaks)
 
Last edited:
Try lowering the 2000 integer value.
  • Custom script: exitwhen udg_i2 > 2000
What is more:
  • Trigger - Run (This trigger) (ignoring conditions)
Remove that action, seriously.

this trigger is to test if it leaks
my mistake
should have said that
but I posted it cause I wasn't sure if I might used something in the execute function which leaks
 
Level 4
Joined
May 4, 2008
Messages
113
Wouldn't it be the GroupEnumUnitsInRange function that is leaking? You haven't destroyed the group there, so it's leaking a unit group.

You need to set all the values to a local group variable and then destroy it at the end of the function.
 
Wouldn't it be the GroupEnumUnitsInRange function that is leaking? You haven't destroyed the group there, so it's leaking a unit group.

You need to set all the values to a local group variable and then destroy it at the end of the function.

nope

that's for the GUI function only cause it CREATES a group
GroupEnumUnitsInRange only works if the group was created already and adds the units to the group instead

I also made a test with destroying the group
it leaked a lot cause it doesn't set free all the memory
 
Level 7
Joined
Nov 6, 2009
Messages
279
made this trigger leak like 10 MB per second

How the hell do you know how much it leaks?

EDIT: make the boolexpr global instead of calling the Condition function all the time.
EDIT2: Blizzard has made DestroyGroup and DestroyTimer really crappy thatz why there are recycling systems.
 
Make sure that the group is clean by clearing it every so often.

JASS:
call GroupClear(g)
does not make a difference but was worth a shot

I can also advise debugging the game and seing where the leak is occuring. It might be a once off leak as it allocates some memory before starting to recycle it.
it's not a game
just a map with these two triggers in it

How the hell do you know how much it leaks?

task manager
not accurate but you can tell the difference between no leak and leak

EDIT: make the boolexpr global instead of calling the Condition function all the time

you can't make global boolexpr variables with GUI/normal JASS afaik

@all people who want me to use JNGP (there always are some who will write something about it and this is just to make the stop spamming me to death)
NO! I WILL IGNORE ANYTHING REGARDING THAT!
(it has nothing to do with the topic anyway)
 
Level 7
Joined
Nov 6, 2009
Messages
279
you can't make global boolexpr variables with GUI/normal JASS afaik

Yeah no boolexpr type at VE... my bad

Link to task manager??? plz??

JNGP IS THE ONLY SOLUTION! YOU CANT LIVE WITHOUT IT! IF YOU DONT USE YOU MUST DIE INSTANTLY CAUSE YOU ARE HUMANITY'S SHAME!

hope u fell for that... (this means im kidding)

EDIT2: Task Manager = Ctrl + Alt + Del?
EDIT3: Task Manager translation in my language sucks
 
Link to task manager??? plz??

EDIT2: Task Manager = Ctrl + Alt + Del?
EDIT3: Task Manager translation in my language sucks

I thought it would only be my country which had the most ugliest language ever :ugly:

Yeah no boolexpr type at VE... my bad
just figured out that one can save boolexprs in hashtables
by doing this I don't require the wrapper function anymore :D
and I don't care about this minor leak any longer since I calculated that group enumerations run 33.333 times per second max usually
(so I will need 20 years to fill the ram with 4 GB of trash until the game breaks)

however if someone is going to figure out why I still would like to know :grin:
 
Make sure that the group is clean by clearing it every so often.

I think enumerations auto-clear. Then again, I think shadow references take up a bit of RAM, so I guess there is no harm in it. =P

Anyway:
JASS:
function EnumStandardFilter takes nothing returns boolean
    set udg_ue = GetFilterUnit()
    return not(IsUnitType(udg_ue,UNIT_TYPE_MECHANICAL)or IsUnitType(udg_ue,UNIT_TYPE_STRUCTURE)or IsUnitType(udg_ue,UNIT_TYPE_DEAD)or IsUnitType(udg_ue,UNIT_TYPE_FLYING)or IsUnitType(udg_ue,UNIT_TYPE_MAGIC_IMMUNE)) and IsUnitEnemy(udg_ue,udg_p)
endfunction

function GroupEnumStandard takes group g, unit u, real x, real y, real r returns nothing
    local boolexpr be = Condition(function EnumStandardFilter)
    set udg_p = GetOwningPlayer(u)
    call GroupEnumUnitsInRange(g, x, y, r, be)
    set be = null
endfunction

Just use the "Condition(function EnumStandardFilter)" directly. But I am not sure if that would fix the problem. Conditions auto-recycle so I don't understand why it'd cause that. Did you test this in a blank map without anything else?

For this:
JASS:
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, r, be)
call DestroyGroup(g)
set g = null

Destroying groups leak a tiny bit of RAM. That's why people recycle groups. =D (Basically, use a global group and just reuse it)

Otherwise, I don't know what causes it. Maybe enumerations take up a little bit of RAM, I dunno. =P It is an interesting find though, but you might want to test it more thoroughly with a null boolexpr or a "return false" dummy condtion just to be sure.
 
Just use the "Condition(function EnumStandardFilter)" directly

d'oh! great idea xD

made some further tests
I changed my trigger to run 50 times every 0.01 sec and it turns out that none of the methods mentioned below leaks (not even the one with null)
however while testing with the old trigger I noticed that the ram usage went up to +10-20 mb and dropped back again after a few seconds (probably the recycling took place during that time)

wrapper function
19 fps
load from hashtable
21 fps
direct conversion
21 fps
null
65 fps (max)

I also tested the null function with ForGroup
it is A LOT faster
but as soon as I added the conditions to the ForGroup actions it was slower
so one shouldn't use filters if the possibility of units being picked while casting stuff is low

will test this a little more anyway cause it is too weird to be true

edit:
made another test
it is 5-10 times faster to enumerate all units without filter and then checking them in the ForGroup function instead of the usual way

I can't really believe this so I'd like someone else to test it

1.
usual enumeration with filter and ForGroup

2.
enumeration with null-filter and ForGroup with "if picked unit is valid do stuff"

both with a few valid and invalid units

edit2:
made another test again which proved the opposite o_O
however it might be possible that null-filters are slower if the condition list is short or if there aren't many targets on the map anyway (e.g. for passive immolation) but since I can make tests with different results I'll stop them now and let the big guys do them

the only things I am sure about now:
-it is pointless to load boolexpressions from hashtables
-null-filter enumerations are fucking fast
-nothing leaks unless you destroy it
-recycling takes some time (which made me think it would leak)

edit3:
made a long-term test and ran a null-filter enumeration 500 million times
after that I had +0.5 MB RAM but it took half an hour so it could be just wc3 itself
however
I will use null-filter enums for GUI now cause I won't need any custom functions (only one line of custom script) and is it much faster and leak-free
 
Last edited:
@Dark: Cool. =D Now I feel like I should get my benchmarks out and start testing stuff. =P

gasp
maybe it's because GroupEnumSingle isn't using
JASS:
 call DestroyBoolExpr(be)

=o

Conditions (boolexprs/filterfuncs in general) auto-recycle so that it reuses it each time, rather than generating a new boolexpr each time. (It generates it once the first time, and then it reuses that over and over rather than creating a new boolexpr) That's why destroying isn't needed. ;)
 
Status
Not open for further replies.
Top