Zombie compartments

  • Revision slug: Zombie_compartments
  • Revision title: Zombie compartments
  • Revision id: 38262
  • Created:
  • Creator: nnethercote
  • Is current revision? No
  • Comment 575 words added, 58 words removed

Revision Content

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.

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 a list of live compartments and you are using Firefox 13 or later, type "about:compartments" into the address bar, and you'll see something like this:

compartments.png

If you are using a version of Firefox earlier than 13 or you want to see how much memory each compartment uses, 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

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})

These mostly are listed in about:compartments in the "System Compartments" section.

Compartments created for web content are listed in about:compartments in the "User Compartments" section.  (They aren't distinguished from system compartments in about:memory, however.)  When looking at user compartments 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:compartments or 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.

In Firefox 13 and later:

  • Restart the browser.
  • Open the page that you think might cause a zombie compartment.
  • Open about:compartments in another tab to confirm that the relevant compartment is present.
  • Close the first page.
  • Reload about:compartments.  Each reload forces garbage collection and cycle collection to happen, which will destroy compartments if possible.  It might be worth refreshing multiple times just to be sure.
  • If the compartment is still present in about:compartments, that's very suspicious.  You could try waiting 20 minutes or so, then reload about:compartments 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.

In Firefox 12 and earlier:

  • 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:compartments 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.

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.

In Firefox 13 and later:

  • Create a new profile.  Install and enable the add-on.
  • Restart the browser.
  • Browse one or more 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 (see above for examples) 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.

In Firefox 12 and earlier:

  • Create a new profile.  Install and enable the add-on.
  • Restart the browser.
  • Browse one or more 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:compartments and close all other pages.
  • Return to about:compartments and reload it, multiple times if necessary.
  • If only system 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.  See Common causes of zombie compartments in extensions for things to avoid.

Revision Source

<p>This page tells you how to detect and avoid <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 a list of live compartments and you are using Firefox 13 or later, type "about:compartments" into the address bar, and you'll see something like this:</p>
<p><img alt="compartments.png" class="internal default" src="/@api/deki/files/6114/=compartments.png"></p>
<p>If you are using a version of Firefox earlier than 13 or you want to see how much memory each compartment uses, 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 <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>These mostly are listed in about:compartments in the "System Compartments" section.</p>
<p>Compartments created for web content are listed in about:compartments in the "User Compartments" section.  (They aren't distinguished from system compartments in about:memory, however.)  When looking at user compartments 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://techcrunch.com/" rel="freelink">http://techcrunch.com/</a>)</code></li> <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=" 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:compartments or 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>
<p>In Firefox 13 and later:</p>
<ul> <li>Restart the browser.</li> <li>Open the page that you think might cause a zombie compartment.</li> <li>Open about:compartments in another tab to confirm that the relevant compartment is present.</li> <li>Close the first page.</li> <li>Reload about:compartments.  Each reload forces garbage collection and cycle collection to happen, which will destroy compartments if possible.  It might be worth refreshing multiple times just to be sure.</li> <li>If the compartment is still present in about:compartments, that's very suspicious.  You could try waiting 20 minutes or so, then reload about:compartments 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 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 <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>In Firefox 12 and earlier:</p>
<ul> <li>Restart the browser.</li> <li>Open the page that you think might cause a zombie compartment.</li> <li>Open about:memory?verbose 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 about:compartments is very helpful (and you can just cut and paste the page contents, there's no need to take a screenshot).  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>
<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>
<p>In Firefox 13 and later:</p>
<ul> <li>Create a new profile.  Install and enable the add-on.</li> <li>Restart the browser.</li> <li>Browse one or more 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.</li> <li>Open about:memory?verbose 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 (see above for examples) 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>In Firefox 12 and earlier:</p>
<ul> <li>Create a new profile.  Install and enable the add-on.</li> <li>Restart the browser.</li> <li>Browse one or more 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.</li> <li>Open about:compartments and close all other pages.</li> <li>Return to about:compartments and reload it, multiple times if necessary.</li> <li>If only system 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>
<h3>Avoiding zombie compartments in add-ons</h3>
<p>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.  See <a href="/en/Extensions/Common_causes_of_zombie_compartments_in_extensions" rel="internal" title="en/Extensions/Common_causes_of_zombie_compartments_in_extensions">Common causes of zombie compartments in extensions</a> for things to avoid.</p>
Revert to this revision