Most objects inside Mozilla-based apps support XPCOM and use reference counting. This works quite well, and in most cases you’ll never have to worry about leaking memory as long as you use nsCOMPtr and related templates to manage your pointers. However, it’s still possible to leak. The most common types of links that I’ve come across:
The first rule of finding memory leaks is to not create them in the first place. An awareness of the above-mentioned issues is invaluable in order to keep the amount of time we spend on this to a minimum. The next step I follow is to start with the absolute minimal use case (starting app and quitting). If there are leaks, those should be fixed first. I’m personally in favor of having a zero leak policy so we can immediately see if something is wrong, but if that’s not feasible (leaks due to Mozilla or some third-party library that can’t be fixed), we should keep them to an absolute minimum and document any that simply can’t be fixed.
Once all the leaks are fixed for the simplest case, then test a slightly more complex case (e.g. open and close navigator) and fix any resulting leaks. By proceeding in this way, you keep the number of leaks to a minimum for each cycle, which makes it much easier to figure out what’s going on.
A good article about finding leaks in Mozilla is David Baron’s Finding leaks in Mozilla.
For finding out whether stuff is leaking and what is leaking, Purify can be very useful. I’ve had success with both debug and release builds of Mozilla. Make sure that you run the app first so that all components are registered. Then start it in Purify. If you have problems like strange error messages appearing, it might help to delete all the files from the Purify cache and trying again. Once you quite Firefox, you’ll see a node in the list of Purify messages that lists all the objects that leaked. Supposedly only real memory leaks (not potential leaks) are interesting. Also, I’m not 100% convinced that Purify catches all leaks.
If your leaks a result of a non-reference counted object or other block of memory, Purify may be all you ever needs to find and fix them. For XPCOM objects, however, it can only tell you that something is leaking and where it was initially allocated. This isn’t that much help since you can’t tell who has addref’ed and released it since then.
In these cases I use my apRefCountLogger class. First of all, make sure that you have the latest patch from bug 322959 applied (and rebuild XPCOM). It only works in debug mode. Then put the following line in the C++ file on the class you want to analyze, directly about the
NS_IMPL_ISUPPORTS
macro:
#include "apRefCountLogger.h"
That’s it. A “leaks.txt” file will appear in your Firefox bin directory on shutdown. If the file is empty, then you have no leaks.
Note that the stackwalking code may interfere with Purify, so remove any references to apRefCountLogger.h from your sources before running Purify.
The most common cause of leaks when using JavaScript and XPConnect is registering a JavaScript listener or observer with a C++ component and forgetting to remove it. This will cause the JavaScript component (anything that it references) to remain in memory. Make absolutely sure that all JavaScript objects registered with C++ components are removed when appropriate (at the latest when the relevant window is closed). Using XPCOM in JavaScript without leaking provides a more complete description of cases where JS/XPCOM leaks may occur.
To find JS/XPCOM leaks, you can use David Baron’s Leak Monitor Extension. This will popup a window when leaks occur and dump remaining leaks to the console on shutdown. If this doesn’t help and you still have leaks, the link at the beginning of this section offers some tips about how to modify the JavaScript and XPConnect sources in order to get detailed logs of all XPConnect activity and leaks.