Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does calling `gc()` manually, result in all `finalizers` being executed immediately?

I have some code that I suspect is leaking memory. As the code uses ccall and maintains significant information held inside pointers, which are supposed to be free'd by code that is ccalled during finalizers.

In my debugging I am calling gc(). And I want to know if this will immediately trigger all finalizers that are attached to the objects that have moved out of scope

Answers should be concerned only with julie 0.5+.

like image 496
Lyndon White Avatar asked Jun 10 '17 02:06

Lyndon White


1 Answers

After the discussion on @Isaiah's answer (deleted), I decided to poke some internals folks and get some clarity on this. As a result, I have it on good authority that when gc() is called at the top level – i.e. not in a local scope – then the following assurance can be relied upon:

if an object is unreachable and you call gc() it’ll be finalized

which is pretty clear cut. The top-level part is significant since when you call gc() in a local scope, local references may or may not be considered reachable, even if they will never be used again.

This assurance does sweep some uncertainty under the carpet of "reachability" since it may not be obvious whether an object is reachable or not because the language runtime may keep references to some objects for various reasons. These reasons should be exhaustively documented, but currently they are not. A couple of notable cases where the runtime holds onto objects are:

  • The unique instance of a singleton type is permanent and will never be collected or finalized;

  • Method caches are also permanent, which in particular, means that modules are not freed when you might otherwise expect them to be since method caches keep references to the modules in which they are defined.

Under "normal circumstances" however – which is what I suspect this question is getting at – yes, calling gc() when an object is no longer reachable will cause it to be collected and finalized "immediately", i.e. before the gc() call returns.

like image 123
StefanKarpinski Avatar answered Sep 21 '22 17:09

StefanKarpinski