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

Reforged LUA leak

Status
Not open for further replies.

KW~

KW~

Level 2
Joined
Feb 7, 2020
Messages
13
I can't find the leak of the code.Does anyone know where it needs to be changed?
Code:
udg_distance = 999999.00
        hx = GetUnitX(gg_unit_Hblm_0001)
        hy = GetUnitY(gg_unit_Hblm_0001)
        local range = 512.00/5
        local g = CreateGroup()
        local b = true
        for n=1,5 do
            local bxp = Condition(function ()
                if (GetFilterUnit() == gg_unit_Hblm_0001) then
                    return false
                else
                    b = false
                    local u = GetFilterUnit()
                    local x = GetUnitX(u)
                    local y = GetUnitY(u)
                    local r = (hx-x)^2+(hy-y)^2
                    if (r < udg_distance) then
                       udg_distance = r
                       udg_unit = u
                    end
                    return true
                end
            end)
            GroupEnumUnitsInRange(g, hx, hy, range*n, bxp)
            DestroyBoolExpr(bxp)
            if ( b == false ) then
                break
            end
        end
        DestroyGroup(g)
        udg_distance = 999999.00
 

KW~

KW~

Level 2
Joined
Feb 7, 2020
Messages
13
You're creating closures, which WC3 is particularly bad at reclaiming. There's no need for you to use a "Condition" here either.
Thanks for your reply. I tried the same code again with jass and found that it was not leaked. Is Lua not suitable for use now? There is another problem, I am a novice, do not use the "condition" how to write code?
 

KW~

KW~

Level 2
Joined
Feb 7, 2020
Messages
13
Lua will only perform a garbage collection cycle once the virtual machine memory usage doubles in size since the result of the last garbage collection cycle. An increase of application address space usage of 2KB is thus not a confirmation that there is a leak.
Thanks for your reply, I will do further testing.
 
Level 9
Joined
Jul 20, 2018
Messages
176
Btw, DestroyBoolExpr(bxp) is not necessary.
It is necessary, because (1) Lua do not cache boolexprs, (2) each time a new function is passed to Condition.
There's no need for you to use a "Condition" here either.
It is not possible to pass not a boolexpr to group filter. Thus, Condition or Filter is necessary. It is possible to omit it is JASS only if you use JassHelper which adds Condition where necessary.

UPD: proof of my words. Code below has next result:
1628615716476.png
Lua:
function TestFilterFuncs()
    local status, err = pcall(function ()
        local g = CreateGroup()
        GroupEnumUnitsInRange(g, 0, 0, 1024, function() return true end)
        DestroyGroup(g)
    end)
    print('Call successful:', status)
    if not status then
        print(err)
    end
end

function SomeFunc()
 
end

function TestConditionCache()
    local cond1 = Filter(SomeFunc)
    local cond2 = Filter(SomeFunc)
 
    print('Filter 1:', cond1, GetHandleId(cond1))
    print('Filter 2:', cond2, GetHandleId(cond2))
end

UPD2: boolexprs creation in JASS do cache them. Code below has next result:
1628616659899.png
JASS:
function DebugMsg takes string s returns nothing
    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0., 0., 5., s)
endfunction

function SomeFunc takes nothing returns nothing
    
endfunction

function BoolexprTest takes nothing returns nothing
    local boolexpr cond1 = Filter(function SomeFunc)
    local boolexpr cond2 = Filter(function SomeFunc)
    call DebugMsg("Filter 1: " + I2S(GetHandleId(cond1)))
    call DebugMsg("Filter 2: " + I2S(GetHandleId(cond2)))
endfunction
 

Attachments

  • Boolexpr testing in jass.w3m
    8.5 KB · Views: 12
  • Boolexpr testing in lua.w3m
    8.2 KB · Views: 17
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
In the Lua case you are passing a new function object to Filter every time it runs.
In the Jass case, you are passing a reference to the same function every time it runs.

In Jass you can only pass a reference to an existing function, in Lua what you do is mostly up to you - you could define the function in a higher scope and reference it just the same.
 
Status
Not open for further replies.
Top