Different ways to force garbage collection

Yesterday I reported a Gecko bug where reproducing required the garbage collector to run. In the following discussion this useful snippet of code appeared:

window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
      .getInterface(Components.interfaces.nsIDOMWindowUtils)
      .garbageCollect();

So if you are suspecting that some issue you are observing is dependent on the garbage collector you can use this to force garbage collector to run. I shared that code at work and promptly got a question: what’s the difference to Components.utils.forceGC()? There we go, yesterday I didn’t even know that there was a way to force garbage collection, and today I already know two!

As to the difference, existing documentation is remarkably reluctant to tell us. I confirmed my guess by looking at the code: Components.utils.forceGC() only triggers the garbage collection mechanism inside the JavaScript engine. That one isn’t aware of XPCOM and will not collect XPCOM objects. nsIDOMWindowUtils.garbageCollect() however goes one step further by triggering the cycle collector, meaning that it will collect both JavaScript and XPCOM objects. And it triggers the cycle collector twice to make sure that it really gets everything. Now it would be nice to see that information on MDC but what would be the right place?

Comments

  • Steve England

    Why does the CC need triggered twice to make sure everything is collected? Is that by design, or a workaround for a bug?

    Wladimir Palant

    Don’t ask me, I am only quoting an IDL comment, I know very little about cycle collector internals. My guess: cycle collector cannot collect some nodes in the first pass because it looks like they are still in use. But it will collect the nodes that are using them. So the remaining nodes will require a second cycle collector pass before they are collected – which is usually not a problem, the cycle collector runs every now and then and a node collected a minute later is ok. It is only a problem when you want to observe the “final result” of the cycle collector. Another question: are two passes always sufficient? Probably not but should be “good enough” in most situations.

  • Mark Finkle

    MDC:

    forceGC already exists
    https://developer.mozilla.org/En/Components.utils
    https://developer.mozilla.org/en/Components.utils.forceGC
    (this could be edited to mention the difference with nsIDOMWindowUtils)

    nsIDOMWindowUtils is not documented, but should be top level and formatted like this one:
    https://developer.mozilla.org/En/NsIDOMWindow

    Wladimir Palant

    I added at least a short note to the forceGC documentation.

  • Eric Shepherd

    I’ve added a section about this to the article “Debugging memory leaks” here:

    https://developer.mozilla.org/En/Debugging_memory_leaks

    Also, Mark’s right, the nsIDOMWindowUtils interface needs to be documented. But it’s not a high priority for me right this minute due to all the Fx 3.1 work still to be done.

  • RIUM+

    I was wondering if the newer TraceMonkey engine in Firefox 3.1 will provide any speed increases to Adblock Plus’s parsing speed? Not that it matters due to how almost-instantaneous Adblock Plus is already, but I was just curious if it will have any effect. :)

    Wladimir Palant

    In my measurements, Firefox 3.1 improved compared to Firefox 3.0 but for some reason TraceMonkey (JIT) had no effect whatsoever.

  • RIUM+

    Even when enabled for the browser chrome, not just for web content? Interesting. I was thinking it would have been one of the better examples of it. Perhaps it’s not enabled for extensions. Or perhaps it really does provide no benefit for ABP.