Zombie compartments

  • Revision slug: Zombie_compartments
  • Revision title: Zombie compartments
  • Revision id: 38243
  • Created:
  • Creator: nnethercote
  • Is current revision? No
  • Comment 1476 words added, 314 words removed

Revision Content

This page tells you how to detect 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.

Compartments

Firefox’s JavaScript memory is segregated into compartments.  Roughly speaking, all memory used by JavaScript code that is from a particular origin (i.e. website) goes into its own compartment.  Firefox’s own JavaScript code also gets one or more compartments.  Compartments improve security and memory locality.

Viewing live compartments

If you want to see the memory usage for each compartment, visit about:memory?verbose 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

The first line says that the compartment used for JavaScript code from www.google.com.au is taking up 5,330,456 bytes.  The lines below that break that memory usage down into further categories, the details of which are not important when looking for zombie compartments.

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)
  • compartment(atoms)
  • compartment(about:home)
  • compartment(about:blank)
  • compartment(moz-nullprincipal:{bb7b47fd-d630-446d-99ca-70315731dcfc})

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.

Zombie compartments

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.

Reactive checking

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.  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.  The more you browse and exercise the add-on, the more thorough the testing will be.
  • 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.

If an add-on is causing zombie compartments, it's not easy to identify why.  However, one common problem is when an add-on contains JavaScript code that holds references to window objects.

Revision Source

<p>This page tells you how to detect <em>zombie compartments</em>, which are a particular kind of memory leak.  They can be caused by bugs in Firefox itself, or by bugs in Firefox add-ons.</p>
<h2>Compartments</h2>
<p>Firefox’s JavaScript memory is segregated into <em><a class="external" href="http://andreasgal.com/2010/10/13/compartments/">compartments</a></em>.  Roughly speaking, all memory used by JavaScript code that is from a particular origin (i.e. website) goes into its own compartment.  Firefox’s own JavaScript code also gets one or more compartments.  Compartments improve security and memory locality.</p>
<h3>Viewing live compartments</h3>
<p>If you want to see the memory usage for each compartment, visit <a href="/about:memory" title="about:memory">about:memory</a><a href="/about:memory?verbose" title="about:memory?verbose">?verbose</a> 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 <code>compartment(...)</code>.  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:</p>
<pre>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
</pre>
<p>The first line says that the compartment used for JavaScript code from www.google.com.au is taking up 5,330,456 bytes.  The lines below that break that memory usage down into further categories, the details of which are not important when looking for zombie compartments.</p>
<h3>When are compartments created?</h3>
<p>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.</p>
<ul> <li><code>compartment([System Principal], 0x7f10f1250000)</code></li> <li><code>compartment(atoms)</code></li> <li><code>compartment(about:home)</code></li> <li><code>compartment(about:blank)</code></li> <li><code>compartment(moz-nullprincipal:{bb7b47fd-d630-446d-99ca-70315731dcfc})</code></li>
</ul>
<p>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.</p>
<ul> <li><code>compartment(<a class=" external" href="http://www.facebook.com/plugins/like.php?..." rel="freelink">http://www.facebook.com/plugins/like.php?...</a>)</code></li> <li><code>compartment(<a class=" external" href="http://techcrunch.com/" rel="freelink">http://techcrunch.com/</a>)</code></li> <li><code>compartment(<a class=" link-https" href="https://plusone.google.com/_/+1/fastbutton?..." rel="freelink">https://plusone.google.com/_/+1/fastbutton?...</a>)</code></li> <li><code>compartment(<a class=" external" href="http://platform.twitter.com/widgets/tweet_button.html?..." rel="freelink">http://platform.twitter.com/widgets/...utton.html?...</a>)</code></li> <li><code>compartment(<a class=" external" href="http://cdn.at.atwola.com/_media/uac/tcode3.html" rel="freelink">http://cdn.at.atwola.com/_media/uac/tcode3.html</a>)</code></li> <li><code>compartment(<a class=" link-https" href="https://s-static.ak.fbcdn.net/connect/xd_proxy.php?..." rel="freelink">https://s-static.ak.fbcdn.net/connec..._proxy.php?...</a>)</code></li> <li><code>compartment(<a class=" external" href="http://ads.tw.adsonar.com/adserving/getAds.jsp?..." rel="freelink">http://ads.tw.adsonar.com/adserving/getAds.jsp?...</a>)</code></li>
</ul>
<p>(Some of those compartment URLs are long and have been truncated.)</p>
<p>Another thing to beware is each compartment is created for an origin (e.g. <a class=" external" href="http://www.facebook.com/" rel="freelink">http://www.facebook.com/</a>), 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 <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668871" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=668871</a> in one tab, then <code>compartment(<a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668871" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=668871</a>)</code> will show up in about:memory?verbose.  If I then open <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=700547" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=700547</a> 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.</p>
<h3>When are compartments destroyed?</h3>
<p>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.</p>
<h2>Zombie compartments</h2>
<p>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.</p>
<h3>Reactive checking</h3>
<p>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.</p>
<ul> <li>Restart the browser.</li> <li>Open the page that you think might cause a zombie compartment.</li> <li>Open <a href="/about:memory?verbose" title="about:memory?verbose">about:memory?verbose</a> in another tab to confirm that the relevant compartment is present.</li> <li>Close the first page.</li> <li>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.</li> <li>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.</li> <li>Some Zombie Compartments are caused by add-ons.  If you have add-ons enabled, please try to reproduce in <a class=" external" href="http://support.mozilla.com/en-US/kb/Safe%20Mode">safe mode</a>, 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.</li> <li>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 <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668871">bug 668871</a>.  Attaching the full contents of <a>about:memory?verbose</a> is very helpful.  See <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=669545">bug 669545</a> for an example.  If the zombie compartment is caused by an add-on, please mark the bug as also blocking <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=700547" title="https://bugzilla.mozilla.org/show_bug.cgi?id=700547">bug 700547</a>.</li>
</ul>
<p>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.</p>
<h3>Proactive checking of add-ons</h3>
<p>It's not uncommon for add-ons to cause zombie compartments, see <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=700547" title="https://bugzilla.mozilla.org/show_bug.cgi?id=700547">bug 700547</a> for examples.  Follow these steps to do some basic checking of an add-on.</p>
<ul> <li>Create a new profile.  Install and enable the add-on.</li> <li>Restart the browser.</li> <li>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.  The more you browse and exercise the add-on, the more thorough the testing will be.</li> <li>Open <a href="/about:memory?verbose" title="about:memory?verbose">about:memory?verbose</a> and close all other pages.</li> <li>Return to about:memory?verbose and hit the "minimize memory usage" button near the bottom, multiple times if necessary.</li> <li>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 <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668871">bug 668871</a> and <a class=" link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=700547" title="https://bugzilla.mozilla.org/show_bug.cgi?id=700547">bug 700547</a>.</li>
</ul>
<p>If an add-on is causing zombie compartments, it's not easy to identify why.  However, one common problem is when an add-on contains JavaScript code that holds references to <code>window</code> objects.</p>
Revert to this revision