This page tells you how to detect and avoid zombie compartments, which are a particular kind of memory leak. They can be caused by bugs in Firefox itself, or by bugs in Firefox add-ons.
Viewing live compartments
If you want to see the memory usage for each compartment, type "about:memory?verbose" into the address bar and look at the "Explicit Allocations" tree at the top. (Nb: The "?verbose" part is important; if you omit that then parts of the "Explicit Allocations" tree will be hidden and you won't see measurements for all compartments.) Each compartment gets a sub-tree that is headed with an entry that says
compartment(...). For example, if you open a tab to www.google.com.au and then refresh about:memory?verbose, you'll see a sub-tree something like this:
5,330,456 B (08.28%) -- compartment(http://www.google.com.au/) ├──2,920,448 B (04.54%) -- gc-heap │ ├──1,032,208 B (01.60%) -- objects │ │ ├────786,192 B (01.22%) -- function │ │ └────246,016 B (00.38%) -- non-function │ ├────683,520 B (01.06%) -- shapes │ │ ├──604,480 B (00.94%) -- tree │ │ └───79,040 B (00.12%) -- dict │ ├────559,520 B (00.87%) -- scripts │ ├────433,456 B (00.67%) -- arena │ │ ├──366,088 B (00.57%) -- unused │ │ ├───44,552 B (00.07%) -- padding │ │ └───22,816 B (00.04%) -- headers │ ├────206,144 B (00.32%) -- type-objects │ └──────5,600 B (00.01%) -- strings ├────822,888 B (01.28%) -- script-data ├────710,208 B (01.10%) -- type-inference │ ├──567,936 B (00.88%) -- script-main │ ├──101,472 B (00.16%) -- object-main │ └───40,800 B (00.06%) -- tables ├────327,680 B (00.51%) -- mjit-code ├────310,768 B (00.48%) -- shapes-extra │ ├──234,240 B (00.36%) -- tree-tables │ ├───46,832 B (00.07%) -- tree-shape-kids │ ├───21,248 B (00.03%) -- dict-tables │ └────8,448 B (00.01%) -- empty-shape-arrays ├────149,536 B (00.23%) -- analysis-temporary ├─────85,880 B (00.13%) -- object-slots └──────3,048 B (00.00%) -- string-chars
When are compartments created?
Any compartments with the following forms are created by Firefox for its own internal use, and can usually be ignored when looking for zombie compartments.
compartment([System Principal], 0x7f10f1250000)
As for compartments created for web content, there are a couple of things to be aware of. First, many sites utilize scripts from other sites to provide advertisements, "like" and "+1" buttons, Twitter feeds, etc. So it's common for multiple compartments to be created for a single web page. For example, if I open www.techcrunch.com the following compartments are created.
(Some of those compartment URLs are long and have been truncated.)
Another thing to beware is each compartment is created for an origin (e.g. http://www.facebook.com/), but the name of the compartment includes all the trailing gunk (e.g. "plugins/like.php?..."). This trailing gunk can be misleading and you shouldn't pay too much attention to it. For example, if I open https://bugzilla.mozilla.org/show_bug.cgi?id=668871 in one tab, then
compartment(https://bugzilla.mozilla.org/show_bug.cgi?id=668871) will show up in about:memory?verbose. If I then open https://bugzilla.mozilla.org/show_bug.cgi?id=700547 and close the first tab, the same compartment will continue to be used. So I'll end up with a compartment whose name doesn't match the only page open from that origin. This can be confusing at first, so be ready for it.
When are compartments destroyed?
Compartments are destroyed when they are garbage collected. This happens some time after the last reference to them disappears. This means there can be a delay between a page being closed and its compartments disappearing.
Sometimes, due to bugs in Firefox and/or add-ons, compartments are created that are never destroyed. These are a particular kind of memory leak, and they cause Firefox's memory usage to increase gradually over time, slowing it down and making it more likely to crash.
If you look at about:memory?verbose and you see a compartment for www.foo.com, but you closed your last www.foo.com tab a while ago, there's a good chance you're seeing a zombie compartment. Follow these steps to make a more conclusive diagnosis.
- Restart the browser.
- Open the page that you think might cause a zombie compartment.
- Open about:memory?verbose in another tab to confirm that the relevant compartment is present.
- Close the first page.
- Return to about:memory?verbose and hit the "minimize memory usage" button near the bottom. This forces garbage collection and cycle collection to happen, which will destroy compartments if possible. It might be worth hitting the button multiple times just to be sure. about:memory?verbose will update each time you press the button.
- If the compartment is still present in about:memory?verbose, that's very suspicious. You could try waiting 20 minutes or so, then hit "minimize memory usage" again. Some zombie compartments stick around for a limited time before disappearing, others are immortal, and it's useful to know which is which.
- Some Zombie Compartments are caused by add-ons. If you have add-ons enabled, please try to reproduce in safe mode, which disables them. If you can identify, by disabling them one at a time, a single add-on that is responsible, that is extremely helpful.
- If you're confident you've found a zombie compartment, please file a bug that includes all the information you've gathered, add “[MemShrink]” to its whiteboard, and mark it as blocking bug 668871. Attaching the full contents of about:memory?verbose is very helpful (and you can just cut and paste the page contents, there's no need to take a screenshot). See bug 669545 for an example. If the zombie compartment is caused by an add-on, please mark the bug as also blocking bug 700547.
It really is best to follow these instructions. In particular, if you have multiple tabs open it's easy to mis-identify whether a compartment should still be alive. If you only have about:memory?verbose open things are much simpler.
Proactive checking of add-ons
It's not uncommon for add-ons to cause zombie compartments, see bug 700547 for examples. Follow these steps to do some basic checking of an add-on.
- Create a new profile. Install and enable the add-on.
- Restart the browser.
- Browse a few pages, and do something that exercises the add-on. For example, for an add-on that remembers passwords, visit a site that requires a password; for an add-on that performs an operation involving a specific page element such as an image or a chunk of text, perform that operation. The more you exercise the add-on, the more thorough the testing will be, but in practice a lot of problems show up quickly.
- Open about:memory?verbose and close all other pages.
- Return to about:memory?verbose and hit the "minimize memory usage" button near the bottom, multiple times if necessary.
- If only internal Firefox compartments are present, congratulations! That's a good sign that the add-on doesn't cause zombie compartments. Otherwise, please file a bug, add "[MemShrink]" to its whiteboard, and mark it as blocking bug 668871 and bug 700547.
Avoiding zombie compartments in add-ons
Once you know that an add-on causes a zombie compartment, the only way to identify the cause is to read the add-on's code.
The most common cause of zombie compartments in add-ons is failure to release resources appropriately when a window is closed or a page unloads.
- Holding onto references to
windowobjects or DOM nodes (such as
window.document) for too long is the most common problem. Some examples: bug 707403, bug 707524, bug 711778.
- Holding onto event observers for too long is another problem. See bug 714509 for an example.