Sunday, October 21, 2007

C++ Garbage

So I've been having conversations about smart/auto pointers and c++ with some of my friends. We all love java and other more modern languages that have garbage collection but there are times when you need to move back into C/C++ land, and rightfully so. I'm not one of those "java/ruby/python is the language to replace all other languages." I use the best tool for the job.

So anyways, one of the most painstaking things about C++ is its absence of garbage collection. Sure, you can always just create things on the stack and pass-by-value but that has its own issue (both in performance and logic). Smart and auto pointers help but don't always give the performance that java gc does. One of the nice things about the GC in java is it is not tied to the owning thread. When an object no longer has any reference to it that thread doesn't block while the object is destroyed. The garbage collector runs in the background, even in parallel, collecting objects smartly that can be destroyed and only doing the work it thinks it can do without consuming too many resources. If I suddenly un-reference or move out of scope a million objects the VM won't necessarily destroy all million right then. It will, over time, destroy them when it thinks it won't hurt performance.


So back to C++. Using C++ templates it isn't difficult to do reference counting on your objects. So what we really need to implement is a singleton garbage collector/reference manager that would keep track of all managed objects, and when they are no longer referenced would mark them to be removed, and then remove them when it thinks its best.

Part 1 Singleton Reference Manager
So first we would need to create a singleton C++ class:

class ReferenceManager
{
public:
static
ReferenceManager* Instance();
protected:
ReferenceManager();
ReferenceManager(const ReferenceManager&);
ReferenceManager& operator= (const ReferenceManager&);


};


Now, if you have never done singletons in C++, the way we insure that one and only one gets created/destroyed is using a local static:

ReferenceManager* ReferenceManager::Instance ()
{
static ReferenceManager inst;
return &inst;
}

This way a local static instance is created the first time this method is called, and after that the same instance is used. Its also important to note that since inst is local static, it will automatically be destroyed when the application terminates.

References can be obtained like this:

ReferenceManager *p1 = ReferenceManager::Instance();
ReferenceManager *p2 = p1->Instance();
ReferenceManager & ref = * ReferenceManager::Instance();

Part 2. Reference Counting:
In my next post I'll create my own smart pointer to do reference counting and communicate its state with this reference manager. I would do that now but its beautiful outside and the lawn needs mowing.

No comments: