Search

Thursday, September 10, 2009

Global variables are bad

Hyderabad Zoological Park

<This post is about C++ (C# folks are saved from this pain)>

One of our devs taking care of NETCF on Nokia S60 reported that after the latest code reached their branch things are working very slow. It was observed that Garbage Collector is getting kicked in way more than it should. Investigation showed something interesting.

I added a global var gcConfig which had a fairly complex constructor and that among other things sets the various member variables like the GC trigger threshold to default value (1mb). All of these works fine on Windows variants.

However, TCPL states “It is generally best to minimize the use of global variables and in particular to limit the use of global variables requiring complicated initialization.”. This is especially true for dlls. We tend to ignore good advice sometimes :)

For Symbian OS (S60) on device complex ctors of global objects are not run (without any warning). The members are all set to 0 (default member initialization). So in the gcConfig GC-trigger was being set to 0 instead of 1mb. The allocation byte count is compared against this value to figure out when it’s time to start a GC. Since it was 0 the collection condition is being met for every allocation and hence for every allocation request GC was being fired!!!

Actually considering that even after that the app was actually running shows that we have pretty good perf ;)

A good alternative of using global vars is as follows

MyClass& useMC()
{
static MyClass mc; // static ensures objects are not created on each call
return mc;
}

MyClass& mc = useMC();

Do note that this has some multi-threading issue. See http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx.

No comments: