RFC: singletons and memory management

Soren Harward stharward at gmail.com
Thu Sep 11 14:16:32 CEST 2008


On Wed, Sep 10, 2008 at 10:58 PM, Seb Ruiz <ruiz at kde.org> wrote:
> Why do you prefer the destroy() method? The less a developer needs to
> know to code the better. Introducing a destroy() method simply
> "reinvents the bike", with the added overhead of needing to relearn
> singleton object destruction.

Here are the reasons I prefer a static destroy() approach over the
other valid approaches for Singletons (smart pointers or setting
s_instance to null at the end of the destructor):

1. It's much more efficient if you happen to double-free the
singleton.  The destroy() method checks to see if the object has
already been destroyed before calling delete on it.  If you call
"delete Singleton::instance()" and the object has already been
destroyed, then you create a whole new Singleton object and
immediately turn around and delete it.  It's wasteful, especially
since Singleton objects are usually fairly resource-intensive to
create and destroy.  This is the number-one big reason not to delete
singletons directly.

2. It allows you to decouple the program releasing control of the
object from the object's actual removal from memory; the destroy()
method means "this object is no longer needed" rather than "this
object must be deleted from memory by the time I finish".  If the
object supports any kind of intelligent garbage collection, such as
the QObject::deleteLater() method, you can use that in the static
destroy() method instead of forcing the destructor to run.  Let's say
you have a destructor that might take a long time to finish (eg, it
creates an XML file to save its state and writes it to an NFS drive).
In a multithreaded program, you can pass actual destruction off to a
totally different garbage-collection thread, and return the current
context immediately to other tasks.  This isn't a really big advantage
for the core Amarok components like EngineController, but could be
useful for peripheral components which don't need to be in memory all
the time, such as the CoverFetcher.

3. Though this probably won't ever happen in Amarok, you *must* use a
static destroy() method which includes properly locking (which I
haven't shown here) if you have multiple threads that could free the
singleton, otherwise you could call the destructor twice
simultaneously and get a segfault when one of them finishes.

And personally speaking, I like the parallelism of the static methods.
 Your constructor and destructor are both private, and you have static
methods to create and destroy the object.

-- 
Soren Harward


More information about the Amarok-devel mailing list