`empty!` and garbage collection for `Tuple`, `NamedTuple`, and `Pairs`

I just started learning garbage collection, so this question may not be well-proposed, please bear with me if I am wrong.

AFAIU, you can empty! a Vector or Dict so that what are inside them will be garbage collected in the future. But for Tuple, NamedTuple, and Pairs, there is no empty! method defined, how could we clear them if I no longer want to refer the things contained in them?

Garbage collection happens automatically, so you shouldn’t normally need to signal to Julia that an object is no longer needed. The garbage collector will only clear an object when it has determined that there are no variables in scope that refer to that object.

Consider this example:

let
    nt = (a = [1, 2], b = [3, 4])
end

After the let block has been executed, there are no more variables in scope that refer to the named tuple (a = [1, 2], b = [3, 4]), so the garbage collector can free the associated memory. (Although the freeing of the memory generally won’t happen immediately.)

Note that empty! is not directly related to garbage collection. Consider this example:

a = [1, 2]
b = [3, 4]
v = [a, b]
empty!(v)

After the call to empty!(v), the memory associated with the vectors [1, 2] and [3, 4] cannot be freed because the variables a and b still refer to them. That memory can only be freed when a and b go out of scope (assuming there aren’t any other references to those vectors that are still in scope).

So, in the uncommon case where you find yourself in a memory limited situation, the way to clear memory is to write your code in such a way that variables that refer to large objects go out of scope as quickly as possible by, e.g., exiting a function. (Though of course if you’re returning the large object from your function, then there will still be a reference to that object in the scope where the function was called.) If worse comes to worst, you can set variables to nothing and then call GC.gc(). But there shouldn’t be too many situations where you actually need to do that.

6 Likes

Garbage collection concerns do not normally apply to tuples/namedtuples/pairs and other data structures that are immutable and bits types. Since they are immutable you cannot empty! them, and since they are normally stack allocated, garbage collection does not apply, and is not needed, just like a plain integer or float does not need garbage collection.

Garbage collection on a tuple (etc.) is a concern if it holds a reference to an object which is heap allocated, like in @CameronBieganek’s example, nt = (a = [1, 2], b = [3, 4]). But then you can empty! the referenced arrays instead, though it’s probably better to leave it to the garbage collector.

2 Likes