Julia v0.6 vs. v0.7 GC behaviour?



I’m a bit unclear about the new v0.7 GC behaviour - I read that GC is more aggressive than on v0.6, but I failed to locate the details.

In Julia v0.7, may a local variable be GC’ed within a function if it’s not used anymore? Can a function argument be GC’ed? So, for example:

function foo()
    A = rand(100)
    # ...
    # A not used from here on
    # ....

function bar(A::Array)
    # do something with A
    # ...
    # A not used from here on
    # ....

Might A be GC’ed after # A not used from here on in foo and/or in bar on Julia v0.7?

When do I need to use the new GC.@preserve (assuming I need to pass a pointer to A to some code, not necessarily via ccall)?

Sorry if there’s already documentation on this - I’d be thankful for a pointer.


It can be GC:ed at any point. AFAIU only cconvert and GC.@preserve have special hooks into the GC to prevent objects being collected.


Thanks! Just for reference - on v0.6, A is safe from GC at least during bar(A), right?


I am not sure of how clever the GC is in 0.6 but there is nothing holding A alive so it would not be a bug to GC it inside bar.


It’s ccall and GC.@preserve. cconvert in other context is otherwise just a normal function.


No (if you mark the containing function @noinline) – function arguments are always protected from GC. This (along with the new GC.@preserve) can help when writing unsafe code which escapes from the provenance of a single ccall (which handles gc-protection automatically).


Thanks, that’s good to know. Will this also be the case on v0.7/v1.0?


There are no long-term guarantees about when something can be GC’d. It will likely continue to be the case in 0.7/1.0 but it might change in any 1.x version. If you need something not to be collected, use GC.@preserve — that’s the only thing that’s guaranteed to work. Anything else is an implementation detail.


Thanks for the clarifications!