Firefox Memory consumption MemShrink

MemShrink progress, week 10

A quieter week this week.  Well, plenty of work was done but not yet completed, and I mostly write only about changes that have been finished.

Now for the bug counts.  (Canned MemShrink bug searches are available here.)

  • P1: 29 (-5, +4)
  • P2: 66 (-6, +8)
  • P3: 37 (-1, +2)
  • Unprioritized: 4 (-1, +4)

There was lots of P1 movement, which is good:  a couple were fixed, some have had enough progress made on them that they were able to be downgraded to P2, and some new problems/opportunities were identified.


about:memory Firefox Garbage Collection Memory allocation Memory consumption MemShrink Tracemonkey Valgrind

MemShrink progress, week 9

Firefox 8 graduated to the Aurora channel this week, and the development period for what will become Firefox 9 began.  Lots of MemShrink activity happened this week, and I think all the changes listed below will make it into Firefox 8.

Avoiding Wasted Memory

I have blogged previously about memory wasted by “clownshoes” bugs.   Ed Morley found a webpage that resulted in 700MB of memory being wasted by the PLArena clownshoes bug.  Basically, on platforms where jemalloc is used (Windows, Linux), half the memory allocated by nsPresArena (which is built on top of PLArena) was wasted.  (On Mac the waste was 11%, because the Mac allocator rounds up less aggressively than jemalloc).

Fixing this problem properly for all PLArenas takes time because it requires changes to NSPR, so I made a spot-fix for the nsPresArena case.  This is a particularly big win on very large pages, but it saves around 3MB even on Gmail. This spot-fix has been granted beta approval and so will, barring disaster, make it into Firefox 7.

A Firefox Nightly user did some measurements with different browsers on the problematic page:

  • Firefox 8.0a1 before patch: 2.0 GB
  • Firefox 8.0a1 after patch: 1.3 GB
  • Latest Chrome canary build and dev (15.0.849.0): 1.1GB
  • Webkit2Process of Safari 5.1: 1.05 GB
  • Internet Explorer 9.0.2: 838 MB
  • Latest Opera Next 12.00: 727 MB

So this fix gets Firefox within spitting distance of other browsers, which is good!

In other developments related to avoiding wasted memory:

  • Luke Wagner discovered that, on typical websites, most JSScripts are byte-compiled but never run.  A JSScript roughly corresponds to a JavaScript function.  In hindsight, it’s not such a surprising result — Firefox byte-compiles all loaded JavaScript code, and you can imagine lots of websites use libraries like jQuery but only use a small fraction of the functions in the library.  Making byte-compilation lazy could potentially save MBs of memory per compartment.  But that will require some non-trivial reworking of the JS engine, and so is unlikely to happen in the short-term.
  • Kyle Huey avoided a small amount (~100KB per browser process) of waste due to rounding up in XPT arenas.

Improving about:memory

I made some progress on a Valgrind tool to help identify the memory that is currently reported only by the “heap-unclassified” bucket in about:memory.  It’s called “DMD”, short for “Dark Matter Detector”.  It’s in early stages and I still need to teach it about most of Firefox’s memory reporters, but it’s already spitting out useful data, which led to me and Ehsan Akhgari landing memory reporters for the JS atom table and the Hunspell spell checker.  We also now have some insight (here and here) about memory usage for very large pages.

Mounir Lamouri turned on the memory reporter for the DOM that he’s been working on for some time.  This shows up under “dom” in about:memory.  There are still some cases that require handling;  you can follow the progress of these here.

Andrew McCreight replaced about:memory’s buttons so you can force a cycle collection without also forcing a garbage collection, which may be useful in hunting down certain problems.

Finally, Sander van Veen added the existing “js-compartments-user” and “js-compartments-system” to the statistics collected by telemetry (his first landed patch!), and I did likewise for the “storage/sqlite” reporter.  I also added a new “tjit-data/trace-monitor” memory reporter that accounts for some of the memory used by TraceMonkey.


Igor Bukanov tweaked the handling of empty chunks by the JavaScript garbage collector.  That sounds boring until you see the results on Gregor Wagner’s 150-tab stress test: resident memory usage dropped 9.5% with all 150 tabs open, and dropped by 27% after all those tabs were closed.

Brian Hackett fixed a memory leak in type inference, which gets it one step closer to being ready to land.

Christian Höltje fixed a leak in his “It’s All Text” add-on that was causing zombie compartments.  This fix will be in version 1.6.0, which is currently awaiting to receive AMO approval, but can be obtained here in the meantime.  This fix and last week’s fix of a memory leak in LastPass are very encouraging — per-compartment reporters in about:memory have, for the first time, given add-on developers a reasonable tool for identifying memory leaks.  I hope we can continue to improve the situation here.  Several people have asked me for documentation on how to avoid memory leaks in add-ons.  I’m not the person to write that guide (I’m not a Gecko expert and I know almost nothing about add-ons) but hopefully someone else can step up to the plate.

Bug counts

Here’s the change in MemShrink bug counts.

  • P1: 30 (-0, +1)
  • P2: 64 (-4, +6)
  • P3: 36 (-5, +0)
  • Unprioritized: 1 (-2, +1)

Good progress on P3 bugs, but they’re the least important ones.  Other than that, new bugs are still being reported faster than they’re being fixed.  If you want to help but don’t know where to start, feel free to email me or ping me on IRC and I’ll do my best to help get you involved.


about:memory Firefox Memory consumption MemShrink

MemShrink progress, week 8

A hodge-podge of things happened this week.

The MemShrink bug counts changed as follows.

  • P1: 29 (-2, +4)
  • P2: 62 (-5, +14)
  • P3: 41 (-0, +6)
  • Unprioritized: 2 (-10, +1)

We actually got through almost all the unprioritized bugs in today’s MemShrink meeting, which was good, but the counts are still going up.  Fortunately, most of the new bugs are ideas for improvement that are reported by developers.  My gut feeling (which I get from reading a lot of memory-related bug reports) is that the number of reports from users about high memory usage are much lower than they were a few months ago.

Firefox Memory consumption MemShrink

Firefox 7 is lean and fast


Firefox 7 uses less memory than Firefox 6 (and 5 and 4): often 20% to 30% less, and sometimes as much as 50% less. In particular, Firefox 7’s memory usage will stay steady if you leave it running overnight, and it will free up more memory when you close many tabs.

This means that Firefox 7 is faster (sometimes drastically so) and less likely to crash, particularly if you have many websites open at once and/or keep Firefox running for a long time between restarts.


Firefox has a reputation for being a memory hog, and the efficiency with which it uses memory has varied over the years. For example, Firefox 2 was quite bad, but Firefox 3, 3.5 and 3.6 were substantially better. But Firefox 4 regressed again, partly due to a large number of new features (not all of which were maximally efficient in their first iteration), and partly due to some over-aggressive tuning of heuristics relating to JavaScript garbage collection and image decoding.

As a result, Mozilla engineers started an effort called MemShrink, the aim of which is to improve Firefox’s speed and stability by reducing its memory usage.  A great deal of progress has been made in only 7 weeks, and thanks to Firefox’s new rapid release cycle, each improvement made will make its way into a final release in only 12–18 weeks. (These improvements are available earlier to users on the Aurora and Beta channels.) Firefox 7 is the first release to benefit from MemShrink’s successes, and the benefits are significant.

Quantifying the improvements

Measuring memory usage is difficult: there are no standard benchmarks, there are several different metrics you can use, and memory usage varies enormously depending on what the browser is doing. Someone who usually has only a handful of tabs open will have an entirely different experience from someone who usually has hundreds of tabs open. (This latter case is not uncommon, by the way, even though the idea of anyone having that many tabs open triggers astonishment and disbelief in many people. E.g. see the comment threads here and here.)

Endurance tests

Dave Hunt and others have been using the MozMill add-on to perform “endurance tests“, where they open and close large numbers of websites and track memory usage in great detail. Dave recently performed an endurance test comparison of development versions of Firefox 6, 7, and 8, repeatedly opening and closing pages from 100 widely used websites in 30 tabs. The following graphs show the average and peak “resident” memory usage for each browser version over five runs of the tests. (“Resident” memory usage is the amount of physical RAM that is being used by Firefox, and is thus arguably the best measure of real machine resources being used.)

Average resident memory usage during endurance tests Peak resident memory usage during endurance test

Obviously the measurements varied significantly between runs. If we do a pair-wise comparison of runs, we see the following relative reductions in memory usage:

  • Minimum resident: 1.1% — 23.5% (median 6.6%)
  • Maximum resident: -3.5% — 17.9% (median 9.6%)
  • Average resident: 4.4% — 27.3% (median 20.0%)

The following two graphs showing how memory usage varied over time during Run 1 for each version. Firefox 6’s graph is first, Firefox 7’s graph is second. (Note: Compare only to the purple “resident” lines; the meaning of the green “explicit” line changed between the versions and so the two green lines cannot be sensibly compared.)

Memory usage of a single run of Firefox 6

Memory usage from a single run of Firefox 7

Firefox 7 is clearly much better; its graph is both lower and has less variation.


Gregor Wagner has a memory stress test called MemBench. It opens 150 websites in succession, one per tab, with a 1.5 second gap between each site. The sites are mostly drawn from Alexa’s Top sites list. I ran this test on 64-bit builds of Firefox 6 and 7 on my Ubuntu Linux machine, which has 16GB of RAM. Each time, I let the stress test complete and then opened about:memory to get measurements for the peak resident usage. Then I hit the “Minimize memory usage” button in about:memory several times until the numbers stabilized again, and then re-measured the resident usage. (Hitting this button is not something normal users do, but it’s useful for testing purposes because causes Firefox to immediately free up memory that would be eventually freed when garbage collection runs.)

For Firefox 6, the peak resident usage was 2,028 MB and the final resident usage was 669 MB. For Firefox 7, the peak usage was 1,851 MB (a 8.7% reduction) and the final usage was 321 MB (a 52.0% reduction). This latter number clearly shows that fragmentation is a much smaller problem in Firefox 7.

(On a related note, Gregor recently measured cutting-edge development versions of Firefox and Google Chrome on MemBench. The results may be surprising to many people.)


Nathan Kirsch from Legit Reviews performed a simple test comparing Firefox 5 against Firefox 7. He clicked “Open all in Tabs” on a bookmark bolder containing 117 bookmarks — causing each bookmark to be opened in a separate tab. Once they all finished loading, he used the Windows Task Manager to measure the “private working set” (which is not that same as “resident”, but will correlate strongly with it). Firefox 7 used half a GB less memory than Firefox 5 — a 39.7% reduction.


Obviously, these tests are synthetic and do not match exactly how users actually use Firefox. (Improved benchmarking is one thing we’re working on as part of MemShrink, but we’ve got a long way to go. ) Nonetheless, the basic operations (opening and closing web pages in tabs) are the same, and we expect the improvements in real usage will mirror improvements in the tests.

This means that users should see Firefox 7 using less memory than earlier versions — often 20% to 30% less, and sometimes as much as 50% less — though the improvements will depend on the exact workload. Indeed, we have had lots of feedback from early users that Firefox 7 feels faster, is more responsive, has fewer pauses, and is generally more pleasant to use than Firefox 4, 5 and 6.

The reduced memory usage should also result in fewer crashes and aborts on Windows, where Firefox is built as a 32-bit application and so is typically restricted to only 2GB of virtual memory.

Mozilla’s MemShrink efforts are continuing. The endurance test results above show that development versions of Firefox 8 already have even better memory usage, and I expect we’ll continue to make further improvements as time goes on. We also have plans to improve our testing infrastructure which should help prevent future regressions in memory usage.

about:memory Firefox Memory consumption MemShrink

MemShrink progress, week 7

Lots of good stuff this week.

Blog posts

There were four great blog posts this week relating to memory usage in Firefox.

Web workers

Ben Turner landed a complete reworking of web workers.  This fixed three MemShrink bugs, and probably a number of others.  Ben also added memory reporters so that web workers show up in about:memory.


I always cringe when someone files a bug report complaining about Firefox’s memory usage and they have many (e.g. 10, 20 or more) add-ons installed.  The chances of all of those add-ons behaving themselves is pretty low, unfortunately.  For example, one user found that the CyberSearch 2.0.8 add-on causes the places SQLite database to grow to over 300MB.  Another user found that one or more add-ons caused that same database to grow to 1.2GB(!);  the add-on(s) responsible has not yet been identified.

This kind of thing is terrible for perceptions of Firefox.  Maybe limiting the size of places.sqlite will help?

In better add-on-related news, Jan Honza Odvarko fixed a bad memory leak in Firebug, one that was causing zombie compartments on pages where Firebug hadn’t even been enabled.  Now Firebug only causes zombie compartments for pages where Firebug has been enabled, but Steve Fink is making progress there, as he described in his blog post that I linked to above.

Two other add-ons known to cause memory problems are Lastpass and It’s All Text.


Andrew McCreight is making great progress on his static analysis to find cycle collection leaks.  This week he found a problem in nsDOMEventTargetWrapperCache, which Olli Pettay then fixed.

If you ask a heap allocator like jemalloc for a certain number of bytes, it’ll often round that request size up to a number such as a power-of-two.  For example, if you ask for 99 bytes it’ll give you 112 or 128.  I found that this is contributing to the high “heap-unclassified” number in about:memory.  I also stumbled across two cases where Firefox itself deliberately requests a power-of-two-sized block of memory (with the aim of avoiding round-up in the heap allocator) but botches the calculation such that it asks for a block slightly bigger than a power-of-two, which jemalloc then rounds up again.  Luke Wagner fixed the first of these, and I have patches awaiting review to fix the second.

Finally, I should mention bug 658738 and its children.  Dão Gottwald and others have been working tirelessly to fix leaked windows in browser-chrome tests.  This has involved both (a) fixing problems with the tests, and (b) fixing problems with the browser.  Eleven child bugs have already been fixed, and there are four still open.

Bug counts

Here’s the change in MemShrink bug counts.

  • P1: 27 (+1)
  • P2: 53 (+4)
  • P3: 35 (+2)
  • P4: 11 (+5)

Increases all across the board.  Once again I think this reflects the increasing amount of work being done… but I keep saying that.  Therefore, beginning next week, I’ll show how many bugs in each category were fixed and how many were added, e.g. “P1: 27 (-2, +3)”.  That’ll give a better idea of progress.  (I can’t start it until next week because I’ve only today started recording enough info about the open bugs to get those numbers.  And before you suggest that I use a time-based Bugzilla search instead, the problem with that is that I write this progress report at a slightly different time each week, so if I just search during the last week I may double-count or fail to count some bugs.)

about:memory Firefox Memory consumption MemShrink

MemShrink progress, week 6

Dave Hunt wrote this week about some endurance tests comparing Firefox 4, 5, 6, 7, and 8, which show how Firefox’s memory usage is improving.  Pay most attention to the ‘resident’ numbers for Firefox 6, 7 and 8, which indicate how much physical memory is being used.  The ‘explicit’ numbers show a big drop between 6 and 7, and then a rise between 7 and 8, but they are suspect, so don’t panic yet.

about:memory improved again this week.  I added a reporter for each compartment’s property table, and two reporters js-compartments-system and js-compartments-user which count how many compartments are present. These latter two will be added to telemetry soon.

I also added a reporter that computes the fraction of the JS heap that is unused, called js-gc-heap-unused-fraction.  The results are surprising — numbers like 30% and 50% are common.  (Some preliminary JS heap visualization helps explain why.)  There are some suggestions for short-term improvements to mitigate this (e.g. smaller GC chunks).  However, I suspect that to fix it properly will require a compacting garbage collector — the current mark and sweep algorithm unavoidably leaves lots of holes all over the heap each time it runs.  But I could be wrong!  GCs have a large design space and there may be other solutions.  A non-compacting generational GC would help in its own way too — fewer objects would reach the general heap and so each full heap collection would likely collect less garbage, and thus leave fewer holes.

Here’s this week’s bug count:

  • P1: 30 (+4)
  • P2: 48 (-1)
  • P3: 33 (+0)
  • Unprioritized: 8 (+2)

It’s nice to see the P2 count go down!  Note that bugs remain unprioritized for two reasons.  First, we don’t always get through all the unprioritized bugs in the MemShrink meeting.  Second, sometimes we ask for more investigation or data before assigning a priority.

On the topic of bugs, I closed the meta-bugs for tracking leaks against Firefox releases, and the one for tracking non-leak memory use reductions, as I mooted last week.  I kept open the one for improving memory-related tools because multiple people though it was useful.

about:memory compartments Firefox Memory consumption MemShrink

MemShrink progress, week 5

There were four main areas of MemShrink progress this week.

Killing zombie compartments

A zombie compartment is one that outlives its tab.  Kyle Huey fixed a very common class of short-lived zombie compartments caused by XmlHttpRequests.  These zombie compartments only lived for a couple of minutes, but this is an important fix because it makes makes memory usage follow tab usage better, and also makes detecting longer-lived zombie compartments much easier.

Alon Zakai has also been doing heroic work tracking down a zombie compartment related to web workers exhibited at  I’m sure he’d appreciate additional help from anyone who might be able to provide it.

Improving about:memory

Lots of progress here.

  • I changed the per-compartment memory reporters so that multiple system compartments with the same name are reported separately, instead of being merged.  This made it obvious that JetPack-based add-ons can have dozens of system compartments.  I don’t know if anybody realized this previously, and it’s something of a concern.  The compartments are currently distinguished in about:memory only by their address, as the following example shows.  system principal including its address
    It would be great to add some identifying information that indicates what part of the code is responsible for creating each system compartment.  That might even give us some much-needed per-add-on accounting.
  • Andrew McCreight added a memory reporter for the cycle collector.
  • I added a memory reporter for the Necko (network) memory cache.
  • Justin Lebar fixed a problem with the image memory reporters, but it bounced due to a possible Tp5 RSS/PrivateBytes regression on Mac.  This was surprising, maybe it was just noise?
  • I changed about:memory so that if there are multiple memory reporters with the same name, you can tell they were merged into a single entry.  For example, in the following screenshot you can easily tell that there were four separate connections to the places database.
    places entry indicating duplication

Acting on memory pressure

Justin Lebar made some great progress on triggering memory pressure events when physical or virtual memory is low on Windows.  See comments 28 and 29 on that bug for some nice graphs showing how this kept Firefox responsive when browsing some very image-intensive sites.  This kind of adaptive behaviour is really important for getting Firefox to behave well on the full range of supported devices, from smartphones all the way up to desktop machines with lots of RAM.  Go Justin!

Tweaking MemShrink processes

The MemShrink wiki page used to be vague about the project’s goals.  So this week I made it more precise.

[The] goal is to get the number of MemShrink P1 bugs down to zero. That will mean that all the bad leaks will have been fixed, and also the important auxiliary work (e.g. infrastructure to detect regressions) will be in place.

As a result, Jeff Muizelaar changed to point to the list of open MemShrink P1 bugs.  It previously pointed to a Tp5 Talos graph.

On a related noted, we have six open meta-bugs for tracking leaks against Firefox releases, one for tracking non-leak memory use reductions, and one for improving memory-related tools.  (These are listed on the wiki.)  I created these bugs before MemShrink meetings started.  But now that we are using the MemShrink whiteboard annotations assiduously, these tracking bugs don’t seem necessary — having two tracking mechanisms is overkill.  In particular, I think their dependencies aren’t being updated consistently.  So I propose to stop using them and close them.  If you have any objections, please let me know and I’ll reconsider.  If I do close them, I’ll make sure that all bugs blocking them have a MemShrink annotation so they won’t fall through the cracks.

And that segues nicely into the MemShrink bug count for this week:

  • P1: 26 (+2)
  • P2: 49 (+0)
  • P3: 33 (+4)
  • Unprioritized: 6 (+4)

Like last week, this increase mostly reflects the fact that people are coming up with new ideas for improvements.

Finally, thanks to Jesse Ruderman for taking minutes at this week’s meeting (and the previous two).

compartments Firefox Memory consumption MemShrink

Zombie compartments! Recognize and report them. Stop the screaming.

Update (November 30, 2011): I wrote a wiki page about zombie compartments.  It’s much clearer than this post, you should read it instead.

Update (July 31, 2011): This blog post has been linked to from‘s front page.  Although any help in improving Firefox’s memory usage is very welcome, please note that this post was aimed at Firefox developers and other technically-inclined users, and I wasn’t expecting its existence to be publicized so widely.   Furthermore, the per-compartment reporters that help identify zombie compartments were only added to Firefox 7 (currently in the Aurora channel), and several existing bugs that cause zombie compartments have been subsequently fixed in the Firefox 8 development code.  This means the hunting of zombie compartments is a sport best left to those who either are using Nightly builds or their own development builds of Firefox.

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.

Per-compartment memory reporters allow you to look at about:memory to see what compartments are present.  Once you close a tab containing a web page, all the compartments associated with that web page should disappear.  (But note that they won’t necessarily disappear immediately;  garbage collection and/or cycle collection has to run first.)

Sometimes this doesn’t happen and you end up with a Zombie Compartment.  This shouldn’t happen, and it indicates a bug.  It also makes children and 1950s B-movie actresses scream.

 1950s B-movie woman screaming

If you notice Zombie Compartments while browsing, please report them to The Authorities.  Here are some steps you can follow when reporting one that will increase the chance it’ll be hunted down.

  • First, you should use about:memory?verbose for diagnosis.  You want the “?verbose” suffix (which you can also get to by clicking the “More verbose” link at the bottom of about:memory) otherwise small compartments might be omitted.
  • Second, beware that many sites utilize scripts from other origins.  Scripts from Google, Facebook and Twitter are particularly common. This means that the most reliable diagnosis of a Zombie Compartment occurs if you do the following: start Firefox anew, open about:memory?verbose and one other tab, then close that other tab, then hit “minimize memory usage” at the bottom of about:memory?verbose several times to force multiple garbage and cycle collections.  (Sometimes hitting it once isn’t enough, I’m not sure why.)  If the compartment remains, it’s very likely a Zombie Compartment.
  • After that, try waiting a while, say 10 or 20 minutes, then try the “minimize memory usage” button 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.  So 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.  Zombie compartments that are caused by add-ons are definitely interesting, but their importance depends on the popularity of the add-on.
  • Finally, 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.

Please, stop the screaming.  Report Zombie Compartments to The Authorities.

Memory consumption MemShrink Performance

Building a page fault benchmark

I wrote a while ago about the importance of avoiding page faults for browser performance.  Despite this, I’ve been focusing specifically on reducing Firefox’s memory usage.  This is not a terrible thing;  page fault rates and memory usage are obviously strongly linked.  But they don’t have perfect correlation.  Not all memory reductions will have equal effect on page faults, and you can easily imagine changes that reduce page fault rates — by changing memory layout and access patterns — without reducing memory consumption.

A couple of days ago, Luke Wagner initiated an interesting email conversation with me about his desire for a page fault benchmark, and I want to write about some of the things we discussed.

It’s not obvious how to design a page fault benchmark, and to understand why I need to first talk about more typical time-based benchmarks like SunSpider.  SunSpider does the same amount of work every time it runs, and you want it to run as fast as possible.  It might take 200ms to run on your beefy desktop machine, 900ms on your netbook, and 2000ms to run on your smartphone.  In all cases, you have a useful baseline against which you can measure optimizations.  Also, any optimization that reduces the time on one device has a good chance of reducing time on the other devices.  The performance curve across devices is fairly flat.

In contrast, if you’re measuring page faults, these things probably won’t be true on a benchmark that does a constant amount of work.  If my desktop machine has 16GB of RAM, I’ll probably get close to zero page faults no matter what happens.  But on a smartphone with 512MB of RAM, the same benchmark may lead to a page fault death spiral;  the number will be enormous, assuming you even bother waiting for it to finish (or the OS doesn’t kill it).  And the netbook will probably lie unhelpfully on one side or the other of the cliff in the performance curve.  Such a benchmark will be of limited use.

However, maybe we can instead concoct a benchmark that repeats a sequence of interesting operations until a certain number of page faults have occurred.  The desktop machine might get 1000 operations, the netbook 400, the smartphone 100.  The performance curve is fairly flat again.

The operations should be representative of realistic browsing behaviour.  Obviously, the memory consumption has to increase each time you finish a sequence, but you don’t want to just open new pages.  A better sequence might look like “open in a new tab, follow some links, do some interaction, open three child pages, close two of them”.

And it would be interesting to run this test on a range of physical memory sizes, to emulate different machines such as smartphones, netbooks, desktops.  Fortunately, you can do this on Linux;  I’m not sure about other OSes.

I think a benchmark (or several benchmarks) like this would be challenging but not impossible to create.  It would be very valuable, because it measures a metric that directly affects users (page faults) rather than one that indirectly affects them (memory consumption).  It would be great to use as the workload under Julian Seward’s VM simulator, in order to find out which parts of the browser are causing page faults.  It might make catch managers’ eyes as much as does.  And finally, it would provide an interesting way to compare the memory “usage” (i.e. the stress put on the memory system) of different browsers, in contrast to comparisons of memory consumption which are difficult to interpret meaningfully.


Firefox Memory consumption MemShrink

MemShrink progress, week 4

Firefox 7 is currently in the Aurora channel.  Its memory usage improvements have been getting a lot of attention this week, with many people reporting the 30% improvement claims from the official blog post.  I was worried about the post claiming a specific percentage improvement, because there are various ways to measure memory usage, and it varies so greatly depending on the workload, but I haven’t seen anybody dispute it so far.  In fact, the only non-Mozilla measurement I saw was one where a reviewer  opened 117 bookmarks at once (one bookmark per tab) and saw a 40% reduction in private bytes on Windows!  This was a pleasant surprise as we were expecting improvements mostly when users (a) closed lots of tabs, or (b) left the browser idle for a long time.

The most significant MemShrink-related landings this week were things that were subsequently backed out.  Paul Biggar landed jemalloc support for Mac, then had to revert it due to some crashes and possible memory usage regressions.  This support has ended up being an enormous hassle, and Paul’s been tirelessly battling various Mac OS X quirks and annoyances over a period of several months.  An earlier appraisal that “It should be pretty trivial… I don’t think any of this would be a ton of work. Maybe a week of trying a few different things and running it through our unit tests?” turned out to be spectacularly wrong.  Hopefully Paul will be able to fix the problems and re-land soon.

Brian Hackett merged his JavaScript type inference from the jaegermonkey repository to the tracemonkey repository.  Type inference speeds up computationally-intensive JavaScript code significantly, but unfortunately it increased memory usage a lot, due to (a) the memory required for the analysis itself, and (b) some extra memory used by the executing JavaScript code.  As a result, Brian had to back it out from the tracemonkey repository.  He’s now making good progress on reducing the overhead.  One reason that this happened is that the jaegermonkey repository gets very little use, so the problem wasn’t noticed until it landed on the tracemonkey repository which gets more use.  So if you want to help Brian out, please try browser builds from the jaegermonkey repository.

On the tools front:

  • Per-compartment memory reporters have found several cases of “zombie compartments”, which is when a tab is closed but one or more of its compartments stay around.  Bug 668871 is tracking these leaks;  if you see any like this please report them there.
  • Benoit Jacob landed some memory reporters for WebGL, which will show up in about:memory, and I fixed a problem that was causing JavaScript typed arrays to erroneously fall into the “heap-unclassified” bucket in about:memory.
  • Speaking of which, that “heap-unclassified” number is still higher than we’d like, often in the 35–45% range.  If you see a particular site that causes “heap-unclassified” to go unusually high, please report it here.

Finally, here’s the MemShrink bug count, with the changes since last week:

  • P1: 24 (+6)
  • P2: 49 (+5)
  • P3: 29 (+4)
  • Unprioritized: 2 (+0)

The increases look bad, but I think that’s not because progress isn’t being made.  Rather, it’s a reflection that MemShrink efforts are still ramping up, and people are coming up with lots of new ideas and filing bugs for them.  The upwards trend will probably continue for several more weeks.