These questions probably need some context: I'm working on an interpreter that will manage memory via reference counted struct types. To deal with the problem of strong reference cycles retaining memory indefinitely, weak references or recursive teardowns have to be used where appropriate.

To help detect memory leaks from within the interpreter, I'd also like to employ core.memory.GC in the following fashion:

* keep core.memory.GC off (disabled) by default, but nonetheless allocate objects from GC memory * provide a function that can find (and reclaim) retained unreachable object graphs that contain strong reference cycles * the main purpose of this function is to find and report such instances, not to reclaim memory. Retained graphs should be reported as warnings on stderr, so that the program can be fixed manually, e.g. by weakening some refs in the proper places
* the function will rely on GC.collect to find unreachable objects
* the function will *always* be called implicitly when a program terminates * the function should also be explicitly callable from any point within a program.

Now my questions:

Is it safe to assume that a call to GC.collect will be handled synchronously (and won't return early)?

Is there a way to ensure that GC.collect will never run unless when called explicitly (even in out of memory situations)?

Is it possible and is it OK to print to stderr while the GC is collecting (e.g. from @nogc code, using functions from core.stdc.stdio)?

Could I implement my function by introducing a shared global flag which is set prior to calling GC.collect and reset afterwards, so that any destructor can determine whether has been invoked by a "flagged" call to GC.collect and act accordingly?

Alternatively: do I need to implement such a flag, or is there already a way in which a destructor can determine whether it has been invoked by the GC?

Thanks for any help!

Reply via email to