Most people complain about garbage collection slowing things down, or causing moments of program hang, but lately D's performance has been pretty awesome in that regard, IMO. No, the problem I have with garbage collection is untraceable errors...

GC.collect() is just this opaque... black box thing, that you have to trust to magically find all the garbage and collect it. When it does, it's awesome. But when it doesn't... you're just screwed. You can't trace through garbage collection, can't debug it, can't examine its inner structures, see what objects are being destructed, or anything as far as I can tell.

So I get something like the following output:
All unit tests have been run successfully.
finalize
core.exception.InvalidMemoryOperationError@src/core/exception.d(693): Invalid 
memory operation
----------------

...and the program exits with status 1. No stack trace, no error reported. Somewhere I've got a null dereference or something, some failure of everything to initialize in the expected order. But I have no way of finding it outside of staring at the code for another 2 hours trying to see anything funny looking.

Trying to break on "exit" with gdb doesn't work either, since D unwinds the stack before exiting in a GC error. Tracing through finalization, the deepest I can get is something called rt_term before there is no more debugging information (despite BUILD=debug being specified). Reading the source in rt/dmain.d myself, I can divine that rt_term calls gc_term, and in gc_term the error is raised. But what functions gc_term calls, you can't even set a breakpoint for. GC.fullCollect() just isn't available. (And gdb doesn't let you do tab completion in D, so I can't list all possible functions similar to that one.)

So... that's my complaint about the D garbage collection. It's frustratingly opaque, impossible to debug, and provides no help whatsoever in its error messages to understanding what went wrong. Garbage collection causes errors after the program has entirely finished, and calling GC.collect() inside a destructor will not only cause the error, it'll completely terminate the program before it finishes the destructor. Speed is great, but debugging with garbage collection is pretty much an endless fount of misery and frustration for me.

Reply via email to