C struct garbage collection not run frequently enough

Thank you! The allocations are due to your TPS object having to live on the heap due to your finalizer:

julia> using AllocCheck

julia> try 
           test!(r, iter)
       catch e
           e.errors[1]
       end
Allocation of TPS in /home/sukera/.julia/packages/GTPSA/YxRfI/src/tps.jl:5
  | t = new(t1)

julia> try 
           test!(r, iter)
       catch e
           e.errors[2]
       end
Allocating runtime call to "jl_f_finalizer" in ./gcutils.jl:87
  | Core.finalizer(f, o)

The allocation can’t be elided because of the unknown lifetime. Since finalizers are not guaranteed to run as soon as the object is “dead”, they accumulate until the next GC run occurs. If I simply insert a GC.gc():

julia> function test!(r, iter)
         for i=1:iter
           normL = 1/sqrt( (1+r[6])^2- r[2]^2 - r[4]^2)
           r[5] = r[5] + normL * (1 + r[6]) - 1
           r[1] = r[1] + normL * r[2]
           r[3] = r[3] + normL * r[4]
           GC.gc()
         end
       end

The continouos high memory usage disappears. Note that “high memory usage” is not always a bad thing - just having “empty” memory around is not magically going to make code more performant.

2 Likes