Categories
about:memory DMD Firefox Memory consumption MemShrink

DMD

I recently landed a new version of DMD on mozilla-central.  DMD is a tool helps us understand and thus reduce Firefox’s memory consumption.  But in order to understand DMD, you first have to understand about:memory.

about:memory

The MemShrink project started about 18 months ago, and it has been very successful in reducing Firefox’s memory consumption.  about:memory is MemShrink’s not-so-secret weapon when it comes to understanding Firefox’s memory consumption.

about:memory screenshot

about:memory has some wonderful characteristics:  it provides literally thousands of measurements;  it’s available in ordinary release builds;  and it’s trivial to run (just type “about:memory” in the address bar).  This means that non-expert users can easily provide developers with detailed measurements if they are having problems.

However, about:memory has two shortcomings.  First, it simply visualizes the data provided by the memory reporter infrastructure.  The coverage provided by this infrastructure is good, but there are still some gaps.  These gaps manifest primarily in the “heap-unclassified” number in about:memory, which represents all the heap allocations that the memory reporters didn’t cover.  Unfortunately, about:memory can provide zero insight into what is within “heap-unclassified”.

Second, it’s hard to verify.  There’s no obvious way to tell if the numbers it gives are accurate (with a few exceptions;  e.g. negative numbers are obviously wrong).  We have established good practices for writing memory reporters (measure sizes, don’t compute then;  traverse data structures rather than maintaining size counters) that prevent most errors, but it’s still quite easy to accidentally count a block of memory twice.

This is where DMD comes in.  It helps with both the heap-unclassified and double-counting problems.

DMD version 1

I wrote the first version of DMD over a year ago.  “DMD” is short for “dark matter detector”, because “heap-unclassified” memory is sometimes jokingly called “dark matter”.

DMD works by intercepting all calls to malloc/free/etc.  This lets DMD track extra information about every heap block, such as where it was allocated.  Furthermore, DMD has hooks into the memory reporters (via functions created with the NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN macro, for those who are interested) so it knows when any heap block is measured by a memory reporter.

With that in place, DMD knows how many times each heap block has been reported.  So, after running the memory reporters, we can up each block into one of the following three groups.

  • Blocks that haven’t been reported indicate gaps in existing memory reporters.  They contribute to “heap-unclassified”.
  • Blocks that have been reported once are good.
  • Blocks that have been reported twice or more indicate defects in existing memory reporters.  They cause some measurements in about:memory to be too high, and “heap-unclassified” to be too low.

DMD presents its results in a sorted fashion that lists the unreported and twice-reported cases that are more important first.

This first version of DMD was implemented as a Valgrind tool, and what’s more, it required a special, patched build of Valgrind to run.  This meant it was difficult to set up, ran very slowly, and could only be used on Linux and Mac.  Despite these shortcomings, it has proved itself extremely useful, helping us get “heap-unclassified” down greatly (on my Linux desktop machine it’s typically between 8 and 12%) and identifying several cases of double-counting.

DMD Version 2

Some time after I wrote the first version of DMD, I realized that all it needed to work was the ability to intercept malloc/free/etc. and to obtain stack traces.  Valgrind was overkill for these purposes — it’s capable of supporting much more invasive tools — and, furthermore, there were existing tools (e.g. trace-malloc) in the Mozilla codebase that did exactly these things.  In other words, it would be possible to build a new version of DMD that integrated directly into the browser.

Work on this new version stalled for a while, because the old one was working well enough.  But then B2G’s Operation Slim Fast started, and it quickly became obvious that “heap-unclassified” on B2G was typically much higher than it was on desktop.  This is primarily because B2G has lots of small processes, and so various unmeasured things that weren’t a big deal on desktop became much more significant on B2G.  And DMD version 1 doesn’t work on B2G devices.

So that provided the impetus to complete the new version.  Mike Hommey finished his new replace-malloc infrastructure recently, which helped greatly, and the new version of DMD landed on mozilla-central last week.  The old version will soon be retired.

DMD now works on Linux, Android, Mac, B2G, and is just shy of working on Windows (where Ehsan Akhgari has been making gradual progress).  It’s also much faster, partly because it avoids the overhead of Valgrind, and partly because it now uses sampling.  The sampling causes blocks smaller than a certain size (4 KiB by default, though you can change that) to be sampled, while blocks larger than that are measured accurately;  this sacrifices a moderate amount of accuracy for a large amount of speed.

Try it

about:memory is wonderful, and DMD is how we make about:memory better.  There are now detailed instructions on how to build DMD, run it, and interpret its output.  It’s quite easy now, requiring only minor changes to the usual build and run steps, and several people have already done it successfully.  Please try it out, and help us further improve about:memory.

Categories
B2G DMD Firefox Memory consumption MemShrink

MemShrink progress, week 77–78

DMD

The big news this week is the landing of the native version of DMD.  The old version of DMD is a Valgrind-based tool that has been instrumental in reducing the size of about:memory’s “heap-unclassified”.  (For example, with trunk builds on my Linux desktop machine it’s now frequently less than 10%.)

However, the old version of DMD wasn’t easy to run.  For example, it required patching Valgrind’s source code and re-building it, among other things.  As a result, only a handful of people ever ran it.  Furthermore, because it’s a Valgrind tool it is very slow and will never run on Windows.

In contrast, the new version is much easier to use.  It just requires a slight configuration change at build time and a slight change in how the browser is invoked.

It’s also much faster, especially if you use the sampling mode which trades a small amount of precision for a great deal of speed.  Crucially, this means it is usable on B2G.  Also, it should be possible for people to use it for long-running sessions, which can be helpful for identifying slow leaks.

And while the new version doesn’t currently run on Windows, it should be fairly straightforward to get it working.  If anyone is interested in helping with this, please contact me, or take a look at the open bug.

I will write a more detailed post about the new version some time in the next few days, once I have updated the documentation and finalized a few more tweaks that should improve usability.  In the meantime, Justin Lebar is already using it in earnest to better understand B2G’s memory consumpion (e.g. see here, here, here, here, here, here, here).

Thanks to Mike Hommey for his excellent replace-malloc infrastructure, on which the new version is built, and to Justin for lots of help, especially with Android and B2G details.

B2G

The option that allows B2G to merge system compartments, previously implemented and landed by Kyle Huey, was enabled by default.  This is a big deal, because it’s the single biggest memory consumption improvement B2G has seen and is likely to see before version 1 is released.

Gabriel Svelto reduced the number of unused dirty pages kept around by jemalloc on B2G.  This can save ~4 MiB of memory across all processes, at a potential cost of making some allocations a little slower.  On a device as memory-constrained as the B2G phones, this is a good trade-off.

Social API

Felipe Gomes reduced the memory consumption of the social API when multiple browser windows are open.  This change has been backported to the beta channel, so it will be present in Firefox 18, in time for the bigger publicity push for this feature.  (For those of you that don’t like Facebook, please note that if you don’t enable the social API it will not affect Firefox’s performance in any way.)

Miscellaneous

I added a MEMORY_VSIZE telemetry reporters, which measures virtual memory consumption.  This might help us understand how many Windows users would benefit from 64-bit builds.

Bug counts

Here are the current bug counts.

  • P1: 17 (-3/+3)
  • P2: 126 (-2/+14)
  • P3: 106 (-4/+7)
  • Unprioritized: 0 (-2/+0)
Categories
B2G Firefox Memory consumption MemShrink

MemShrink progress, week 75–76

B2G continues to be a major focus of work relating to memory consumption.  Even the non-B2G-specific improvements made this fortnight were mostly identified and made to help B2G.

B2G-specific

Gabriele Svelto caused dirty freed pages held onto by jemalloc to be purged when a B2G process experiences memory pressure, such as when it goes into the background.  This typically reduces a process’ size by about 2 MiB, so it’s a big deal.  This was a MemShrink P1 bug.

Benoit Jacob prevented the creation of redundant OpenGL contexts on B2G.  This saves 750 KiB in the main B2G process, and 750 KiB in every child that uses WebGL.  Benoit was able to do this based on data from a B2G-specific heap profiler written by Justin Lebar.

I made a large IPC message buffer shrink once all messages from it have been processed.  This saves either 120 KiB or 248 KiB per child process.

James Lal greatly reduced memory consumption of the ical parser during sync.  This change also made it much faster.

Justin Lebar and I added a memory reporter for Freetype, which uses about 2 MiB of memory in the main B2G process.  (This reporter also works on Fennec.)

Andrea Marchesini added a memory reporter for B2G’s gralloc memory.

Miscellaneous

Bill McCloskey made the JavaScript engine clean up more data on memory pressure events.

I increased the size of the chunks used by XPT info’s arena allocator, which saves about 80 KiB per process on 32-bit, and a bit more on 64-bit.

Randell Jesup fixed a PeerConnection leak in WebRTC code.

I added more detail to the JavaScript type inference memory reporters.

Bug counts

Here are the current bug counts.

  • P1: 17 (-4/+1)
  • P2: 114 (-5/+9)
  • P3: 103 (-4/+5)
  • Unprioritized: 2 (-3/+1)
Categories
about:memory add-ons B2G Fennec Firefox Memory consumption MemShrink

MemShrink progress, week 73–74

B2G!  Fennec!  Social API!  They’re all happening, and memory consumption is a big deal for all of them.  Time for a MemShrink report.

B2G

Lots of B2G work is happening, unsurprisingly.  All of these changes have been backported to the Aurora channel.

Kyle Huey landed an important patch that merges system compartments together.  This avoids wasted space caused by having 100s of small compartments.  As Chris Jones said: “It’s a completely different phone with these patches.”  Unfortunately, the preference controlling this behaviour is currently turned off on B2G, because it’s causing some Marionette test failures.  Hopefully they’ll be dealt with soon.  Note that this preference won’t be turned on in desktop builds, and there’s a medium-term plan to avoid this wasted space in a less hacky fashion.

Marco Bonardo disabled Places in B2G, saving about 300 KiB in the main process.

Justin Lebar added code to trigger memory pressure events when lowmemkiller notifications occur.

Justin also tweaked things so that the garbage collector is more likely to run when screenshots are taken.

Jeff Muizelaar fixed a graphics bug that I don’t understand but apparently avoids allocating lots of memory on the B2G unlock screen.

Chris Jones ensured that remote content drop their buffers when they’re hidden.

I tweaked the size of the arena chunks used by XPT, which saved about 120 KiB per process on 64-bit builds, and a bit less on 32-bit builds.

I also shrunk the initial size of the SPS hash table, which saves 48 KiB per process on 64-bit builds and 24 KiB on 32-bit builds.

Memory Reporting

Lots of work happened on the memory reporting front.  This was inspired by  “heap-unclassified” typically being much higher on B2G than on desktop.  Desktop Firefox uses a single process and its memory consumption is usually measured in the 100s of MiBs or more.  In contrast, B2G uses one “main” process and then one process per running app, and the smaller ones are typically around 10 MiB.  As a result, the sundry small per-process things that don’t matter much for desktop loom larger on B2G.  (For the same reason, changes that reduce per-process memory by smallish amounts have outsize value on B2G.)  Most of the following changes have also been backported to the Aurora channel.

Nick Hurley added a “explicit/network/disk-cache” memory reporter.  It typically measures 100s of KiBs in desktop Firefox.  (It doesn’t get used on B2G.)

I added memory reporters “explicit/xpcom/component-manager” and “explicit/xpcom/category-manager”.  Together they measure about 280 KiB per process on 64-bit builds, and a bit less on 32-bit builds.

I added a memory reporter “explicit/script-namespace-manager”.  It measures just over 150 KiB per process on 64-bit builds, and a bit less on 32-bit builds.

I added a memory reporter “explicit/xpcom/effective-TLD-service”.  It measures about 128 KiB per process on 64-bit builds, and a bit less on 32-bit builds.

I added some detail to the JS object memory reporters.  This gives slightly more insight into where this memory is going, but the extra memory measured as a result is usually pretty small.

I fixed the “explicit/atom-tables” memory reporter, which was erroneously always reporting 0 bytes.  It now measures anywhere from a few 100 KiBs to several MiBs of memory.  This was a frustrating bug to find.  DMD exists to check that memory reporters are measuring memory properly, and the reporter was doing its measurements just fine.  But DMD cannot check that the measured amounts are added correctly, and that’s what was going wrong here — a line that should have been this:

return n;

instead was this:

return 0;

In other words, the code I had written was doing the difficult part correctly, but botched the trivial part.  How annoying.

Social API

Felipe Gomes fixed a document leak that occurred when the social sidebar was hidden, and disappeared only when it was unhidden.

Felipe also added code to clear the previous profile when Social is toggled off, which prevents a leak.

The social API still has some significant unresolved memory consumption issues, which are a concern.

Fennec

Kartikaya Gupta (a.k.a. Kats) turned on tab expiration for Fennec.  What this means is that Fennec will now unload the contents of background tabs in certain circumstances — when memory is low, and in some cases when a tab hasn’t been viewed for over an hour — and then reload them when they are brought back into the foreground.  Read Kats’ blog post for more details.

(This change was prompted by Project 256meg, which aims to make Fennec usable on phones with only 256 MiB of RAM.  (Fennec currently requires 512 MiB, according to the official specs.)  Kats has just got to the point where Fennec can actually start on 256 MiB devices.  Although Fennec only uses a single process, there is obviously significant overlap between this goal and B2G’s memory reduction goals.)

An obvious follow-up idea is to add tab expiration to desktop Firefox.  But the bug tracking that idea has seen more heated discussion.  The reason is that tab expiration might cause data loss in some cases.  This is less of a problem on Fennec because (as far as I can tell) there is less of an expectation that in-flight data will be saved on mobile devices.  For example, having processes killed due to memory constraints on mobile is much more common than on desktop.  Still, I expect plenty more arguing before this issue is resolved one way or the other.  One option is to allow it on desktop but have it disabled by default.

Add-ons

Michel Gutierrez fixed a zombie compartment in Video DownloadHelper, which is the 2nd most popular add-on at AMO.   Version 4.9.11 has the fix.

We hit a notable milestone on the add-on front this fortnight:  on November 1st hit bug for tracking known leaks in add-ons — filed 16 months ago — had zero blockers.  In other words, we reached the point where no add-ons were known to leak!  Unfortunately this didn’t last long, and at the time of writing the tracking bug has three blocking bugs.  Still, it’s confirmation that what used to be our biggest memory consumption problem is well under control.

Bug Counts

Here are the current bug counts.

  • P1: 20 (-3/+5)
  • P2: 110 (-10/+7)
  • P3: 102 (-3/+8)
  • Unprioritized: 4 (-2/+4)

As always, the current bug lists can be found by following the links on the MemShrink wiki page.

Categories
add-ons B2G Firefox Memory consumption MemShrink

MemShrink progress, week 71–72

B2G

Justin Lebar led the B2G charge this fortnight, doing the following.

Thinker Li identified that we were using overly large (128 KiB) arena chunks for type inference data in the JS engine.  Reducing them to 32 KiB saved over 3 MiB of memory on B2G.

Fabrice Desré disabled the add-on manager services, saving about 1 MiB.

These changes have all been backported to Aurora, because that’s the current home of the code that will be used for the V1 release of B2G.

Social API

Jared Wein modified the social sidebar so that it unloads itself 10 seconds after it’s been hidden.  This is good because lots of people thought that closing the sidebar was equivalent to disabling the social functionality, and with this change it now effectively is.

Felipe Gomes fixed a major problem which caused the social API to create and leak many unnecessary ports.

Gecko & SpiderMonkey

Benoit Jacob fixed a leak relating to WebGL and cycle collection.  This fixed 10 seconds pauses that occurred after running the RO.ME demo, and also fixed leaks seen in the WebGL version of Nokia Maps.

Kyle Huey fixed a bug that was causing storage code to leak one thread per connection.  This doesn’t affect most Firefox users much, because most connections live for the full lifetime of the process.  However, it could affect some add-ons, and it helped avoid some frequent OOM oranges in some of our tests.

Benjamin Peterson reduced the amount of memory used to compress JavaScript source code.

Add-ons

Zig fixed a zombie compartment in the Visited add-on.

Bug Counts

Here are the current bug counts.

  • P1: 18 (-4/+3)
  • P2: 113 (-2/+14)
  • P3: 97 (-1/+7)
  • Unprioritized: 2 (-13/+2)

Note:  in all my previous MemShrink reports, I mentioned bug fixes as soon as they landed on mozilla-inbound.  As of this week, I’m changing things so that I (mostly) only mention bug fixes that have landed on mozilla-central and thus been marked as RESOLVED.  This will make my life easier (tracking RESOLVED bugs is easy with Bugzilla search), and it will also mean that the changes in bug counts better match the descriptions of bug fixes.  But it means that some bug fixes will be reported two weeks later than they previously would.

Categories
about:memory add-ons B2G DMD Firefox Memory consumption MemShrink

MemShrink Progress, week 69–70

It’s been a bumper two weeks for MemShrink.

B2G

Gregor Wagner tweaked the JS garbage collection heuristics on B2G so that collections occur more frequently.  This prevents too much garbage from accruing, which is important on low-memory B2G devices.

Justin Lebar disabled sync on B2G, because it isn’t used.

Justin also implemented the ability to dump GC/CC logs when a particular signal is received, which is particularly useful for B2G.

B2G’s Operation Slim Fast is in full swing.  Please see the tracking bug for details about what is happening.  While there are a number of important fixes in the pipeline, memory consumption is still a critical issue for B2G simply because the devices don’t have much memory in the first place.  Any additional help from Mozilla developers will be greatly appreciated.  For example, if anyone can help identify unnecessary compartments, that would be helpful.

Memory Reporting

Boris Zbarsky improved the reporting coverage of style sheets.  We’ve seen this improved coverage account for over 1% of explicit on desktop and over 2% of explicit on B2G.

I fixed some double-counting of style sheets, and slightly improved the reporting coverage of style sheets and JS compartments.

Nathan Froyd added memory reporting for telemetry.

Justin Lebar fixed some over-reporting of the JS stack.  Justin also added to about:memory the ability to read JSON memory report data from the clipboard.

I renamed DMD as DMDV, in preparation for its in-progress, non-Valgrind replacement to take over the original name.

Testing With Valgrind

Gary Kwong has done some heroic work recently getting Valgrind tests passing on Tinderbox.  (Strictly speaking, the tests run Memcheck, which is the default Valgrind tool and is synonymous with Valgrind)  His blog post about it is well worth reading.

This is important for MemShrink because Memcheck can detect an important class of memory leaks — ones where all references to a block of memory are lost and so the block leaks forever.  But it’s also important for Firefox as a whole because Memcheck can detect a slew of other memory-related errors, such as writing unaddressable memory (e.g. buffer overruns) and using undefined values in dangerous ways.  These are the kinds of defects that cause crashes, security vulnerabilities, and other major problems.

The tests are currently hidden on TBPL because they only run on mozilla-central once a day, which is generally not enough for a test suite to be reliable enough to be worth unhiding.  Having said that, the ability to write suppressions for errors found with Memcheck complicates considerations;  see bug 800435 for further discussion.

Add-ons

Gregg Lind fixed things so that our Aurora/Beta users are certain to get an up-to-date, non-leaky version of the Test Pilot add-on.  (Version 1.1.2 was the leaky version;  version 1.2.0 or later has the fix.)  This was a longstanding MemShrink:P1 bug.

Erik Vold fixed a zombie compartment in Scriptish.  Version 0.1.8 has the fix.

Josep del Rio fixed a zombie compartment in Speed Dial.  Version 0.9.6.10 has the fix.

Miscellaneous

Boris Zbarsky fixed a bad zombie compartment leak relating to expandos.  This was a recent regression, and the fix is present on Aurora and Beta.  The problem was first reported in the comments of my MemShrink report from four weeks ago — many thanks to Alex for reporting it and preventing it from reaching an official Firefox release!

Bug Counts

Here are the current bug counts.

  • P1: 19 (-2/+5)
  • P2: 101 (-2/+6)
  • P3: 91 (-6/+0)
  • Unprioritized: 13 (-1/+11)

The unprioritized count is high because we spent the first part of today’s MemShrink meeting talking with Gavin Sharp, Jared Wein and Felipe Gomes about the upcoming social API, and then spent some additional time discussing B2G with David Clarke.  As a result we didn’t have time to triage the 23 new MemShrink bugs.  We’ve scheduled an out-of-band MemShrink meeting for next week to get on top of the bug list.

Visiting Mountain View

I’ll be in Mountain View all next week for the JS team work week.  I’ll be happy to meet up with anyone who wants to talk about memory consumption!

Categories
B2G Firefox Memory consumption MemShrink

MemShrink progress, week 67–68

It’s been a busy couple of weeks for MemShrink.

B2G Memory Reporting

about:memory is our main tool for understanding memory consumption. On desktop Firefox it works very well.  On Firefox mobile it works less well, partly because it’s hard to read all that text on a small screen, and partly because you can’t cut and paste, which makes bug reporting difficult.  And on B2G (a.k.a. Firefox OS) it currently doesn’t work at all.

To remedy this, I implemented the ability to import and export memory reporter data in JSON format, and Justin Lebar sped up the exporting of this data and implemented a signal-based mechanism for triggering it.  The idea is that developers can trigger an export of the data from their device and then view it in about:memory in desktop Firefox.

This will allow detailed memory profiling for B2G, which I have listed as #3 on the current MemShrink “big ticket items” list.  The timing is good, because B2G has reached feature-freeze and so focus will now move to its performance and memory consumption as part of “Operation Slim Fast“.

(On a related note, Kartikaya Gupta and other engineers have started looking closely at the memory consumption of Firefox mobile on low-end devices.)

Generic Memory Reporting

I added memory reporting to IonMonkey.  Happily, it appears to use very little memory, especially compared with JaegerMonkey.  This is partly because it generates smaller code than JaegerMonkey, but mostly it’s because IonMonkey is only used to compile the small fraction of code that has been executed many 1000s of times.  In comparison, JaegerMonkey is used to compile the much larger fraction of code that has been executed more than a few times.

Kyle Huey added memory reporters for attribute nodes and attribute maps, which improves the coverage of the memory reporting for the DOM.

Gecko Slimmings

Kyle Huey optimized the representation of repeated inline style rules.  This means that for pages with many elements of the form <foo style="blah">, the repeated style="blah" part is now shared between the elements.  This is a huge win on certain large, auto-generated pages.  For example, on one page that holds a gigantic Mercurial diff, this change reduced 64-bit Firefox’s memory consumption from 1,759 MiB to 1,306 MiB.

Kyle Huey and Olli Pettay fixed a leak relating to web workers.

Patrick McManus fixed a leak in network code that was causing intermittent oranges for Mochitests.

Seth Fowler made nsConsoleService only post a LogMessageRunnable to the event queue if there are any observers for it.  This can save a lot of memory for pages that contains many errors.

Bad Graphics Drivers

An ongoing problem we have is that badly-written graphics drivers can cause outlandish (e.g. multi-GB) memory consumption.  Here’s one example that was fixed by blocklisting one particular AMD driver.  (That driver was also causing lots of crashes.)

It’s got to the point that if someone is seeing excessive memory consumption with no apparent explanation — e.g. immediately after start-up, with few tabs open — I’ll suggest they set layers.acceleration.disabled to true in about:config and there’s a good chance it’ll fix the problem.  (Restarting in safe mode also disables hardware acceleration.)  I don’t have any good ideas on how to improve this situation.

Bug Counts

Here are the current bug counts.

  • P1: 16 (-8/+3)
  • P2: 97 (-2/+10)
  • P3: 97 (-6/+3)
  • Unprioritized: 3 (-3/+3)

In today’s MemShrink meeting we closed and downgraded a number of P1 bugs that (a) have been partially addressed, or (b) are less important than they first seemed, or (c) are duplicates.

Categories
Firefox Garbage Collection Memory consumption MemShrink

MemShrink progress, week 65–66

Gecko

Tim Taubert set the style of a not-yet-restored tab’s <browser> element to display:none, eliminating the need for any layout data to be stored in memory for such a tab.  This was a MemShrink:P1 bug and is a nice improvement for users who typically have many (e.g. 100+) tabs open, because it saves 0.17MB per not-yet-restored tab on 64-bit platforms, and slightly less on 32-bit platforms.

Bobby Holley fixed a defect that was causing some add-ons (NoScript, Roboform, and Google PageSpeed) to create ghost windows.   This fix has been also been ported to the Aurora and Beta channels and so will be present in Firefox 16.

Add-on SDK

Version 1.10 of the Add-on SDK was released.  It has two fixes that prevent various leaks.  Furthermore, Alexandre Poirot fixed two other leaks in the Add-on SDK;  these changes will presumably make it into version 1.11.

The Add-on SDK has had a lot of leaks fixed over the past few months.  Hopefully we’re getting near the end of them!

Generational GC

I have started helping with the ongoing project to convert the JavaScript engine’s mark-and-sweep garbage collector to a compacting, generational collector.  This is the #2 item on the current MemShrink “Big Ticket Items” list because it should significantly reduce JS memory consumption, and it should also help performance in other ways.

It’s a big task because it makes a very fundamental change to the JS engine: garbage-collected things such as JS objects, strings and functions can move.  This is a big deal because these things are represented within the JS engine as C++ objects of various kinds, and it’s not normal for C++ objects to move!  Think about it — if you have a pointer to a C++ object, and the object moves, the pointer is no longer valid.

I won’t go into detail about how we handle this but the important thing to know is that pretty much every place in the JS engine where we have a raw C++ pointer to a GC thing object needs to be manually changed to use a new representation.  This is literally tens of thousands of changes that must be completed before the garbage collector can be made either compacting or generational (the two properties are orthogonal, with both providing benefits).

If you are interested in following the progress of this conversion, take a look at bug 753203.

A reminder

In these MemShrink reports I usually write about Firefox changes just after they first land on mozilla-central.  Such changes will show up in Nightly builds within a day, but won’t reach an official Firefox release for 12–18 weeks, as per Firefox’s release schedule.  If you remember that you’ll avoid any confusion about which changes are in which release.

For example:  except where noted otherwise, the changes I’ve mentioned above will be in Firefox 18 — assuming they don’t cause problems that cause them to be backed out — which is due for final release in early January, 2013. (The current scheduled release date is January 1st, but that will probably be delayed slightly because New Year’s Day is not a good day for a release!)

Bug Counts

Here are the current bug counts.

  • P1: 21 (-1/+0)
  • P2: 89 (-5/+4)
  • P3: 100 (-3/+7)
  • Unprioritized: 3 (-2/+3)
Categories
add-ons Firefox Memory consumption MemShrink

MemShrink progress, week 63–64

Add-ons

The big news this week was the release of Firefox 15, which prevents most add-on memory leaks.  As a consequence, we were able to close open bug reports for several add-ons that no longer leak:  Firebug (yay!), Enter Selects, LinkResolve, We-Care Reminder, Restartless Restart + SmartSearch (the leak happened only when both were installed).

Although Firefox 15 prevents most zombie compartment leaks, some remain.

  • Scriptish still leaks.  Scriptish is a GreaseMonkey fork.  Fortunately it has many fewer users than GreaseMonkey.
  • Speed Dial creates a zombie compartment when adding a new page to the speed dial.  This was only just reported, so we don’t yet know if it pre-dated Firefox 15 or not.

I haven’t heard much feedback about the release from actual users. This is probably a good thing, as users are much more likely to notice and report problems than improvements.  One thing that has cropped up is that a small number of add-ons have had their functionality adversely affected by the change, i.e. they were accessing compartments for a page after the page has been closed.

  • This caused certain GreaseMonkey scripts to leak badly.  This has now been fixed.
  • AutoPager’s main functionality is now broken.  On the upside, it no longer leaks.  AutoPager’s author hasn’t been responsive for the past five months, unfortunately.
  • TabMix Plus is popping up some error windows that it shouldn’t.
  • Two users with many add-ons installed have reported increased memory consumption.  The add-on(s) responsible haven’t been identified yet.

If you have any additional add-ons that you think have been adversely affected by Firefox 15, open the error console and use the “filter” search box in the top right-hand corner to look for a message that says “TypeError: can’t access dead object” — that’s the message that indicates an add-on is trying to access memory via a reference that Firefox 15 has pre-emptively cut.  Please report any problems in Bugzilla and put “[MemShrink]” in the whiteboard field.

On a related note, the discussion of Firefox 15’s release on various tech sites prompted me to debunk the common misconception that Mozilla claims “this is the release that fixes the memory leaks” on every release.

Other stuff

Andrew McCreight fixed a problem involving the cycle collector that could cause occasional leaks.

Brian Nicholson roughly halved the amount of memory used in Firefox Mobile’s page readability check.  (This wasn’t actually marked as a MemShrink bug;  I just chanced upon it today when looking at TBPL.)

Nick Cameron fixed a small, obscure leak.

Google Reader

For quite a while now we’ve had various people say that Google Reader creates lots of windows and/or compartments and causes Firefox’s memory consumption to gradually increase when it’s open for a long time.  This may only happen if you are signed into a Google+ account.  It feels like it’s a problem with Google Reader itself rather than Firefox, and a Google Reader engineer is CC’d on the bug report, but no progress has been made, and the reported symptoms are on the vague side.

If you have experienced this, we’d love to hear your feedback in the bug report.  In particular, as always, reliable steps to reproduce would make a big difference.

Bug Counts

Here are the current bug counts.

  • P1: 22 (-3/+1)
  • P2: 90 (-2/+3)
  • P3: 96 (-9/+7)
  • Unprioritized: 2 (-2/+2)

Forward progress!  Good to see.

Categories
Firefox Memory consumption MemShrink

Debunking A Misconception About Firefox Releases

There is a common misconception that every time a new release of Firefox comes out Mozilla claims “this is the one that fixes the memory consumption problems”.  I see this misconception in action all the time.

The Misconception in Action

Here are some recent examples.

Reddit example 1:

NEXT VERSION OF FIREFOX IMPROVES MEMORY USAGE

Holy crap!!!

Oh wait, I feel like I’ve heard this before. Oh yea, with ever. single. new firefox release in the last 3 years. Every one.

Reddit example 2:

“Firefox 14 fixes the memory leak problem!”

“Firefox 13 finally addresses the leaky memory issue!”

“Firefox 12 – better on memory. No more leaks!”

“Firefox 11 – finally solving the leaky memory problem.”

etc etc etc

I’ll believe it when I see it.

Reddit example 3:

Firefox has finally fixed the add-on memory leak for about 10 versions now.

Hacker News example 1:

I’m not sure when Firefox got so memory-hungry and leaky, but it’s the single reason I keep jumping around to Chromium and Opera. Really, really hoping that this time is for real. It’s not the first time a blog post like this has been posted by Mozilla.

Hacker New example 2:

How many releases of firefox have we had now that claim to have fixed its memory problems? I make this at least four, which is a few too many for me to believe it this time.

Ars Technica example:

“Firefox 15 introduces a new optimization that can radically reduce the browser’s memory footprint…”

Haven’t they been saying this since Firefox 11?

This drives me crazy, because it’s simply not true.

Debunking the misconception

I looked at the announcements on the official Mozilla Blog for all the releases between Firefox 4 (March 2011) to Firefox 15 (today):  4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15.  Only three of them even mentioned the word “memory”.

  • Firefox 7.  The headline says “Mozilla Firefox Significantly Reduces Memory Use to Make Web Browsing Faster”.  The text includes: “Firefox manages memory more efficiently to deliver a nimble Web browsing experience. Users will notice Firefox is faster at opening new tabs, clicking on menu items and buttons on websites. Heavy Internet users will enjoy enhanced performance when lots of tabs are open and during long Web browsing sessions that last hours or even days.”
  • Firefox 13. The text includes: “Firefox loads tabs on demand when restoring a browsing session to more quickly get you to Web pages. Firefox first loads the tab you are currently viewing, then loads background tabs when you click them. It’s an improvement that makes Firefox start faster and use less memory.”
  • Firefox 15. The headline includes: “Firefox Now Uses Less Memory to Make Browsing Faster”.  The text says: “Firefox makes your Web experience faster by reducing memory usage when browsing with certain add-ons. The improvements make browsing smoother and more responsive.”

That’s two major mentions of memory consumption, and one minor mention, in twelve release announcements.  The major mentions were warranted — Firefox 7 greatly reduced memory consumption for Firefox itself, and Firefox 15 greatly reduced memory consumption in many cases for users with add-ons.  And the claims about improvements are clearly qualified to indicate in which circumstances they will be noticed.

But what about the release notes?  After all, although they are less prominent than the announcements on the Mozilla Blog, they’re arguably a more official description of the changes in each release.  Of the twelve releases since Firefox 4, only four of them had release notes that mentioned the word “memory”.

  • Firefox 15: “Optimized memory usage for add-ons”.
  • Firefox 8/8.0.1: “Improved performance and memory handling when using <audio> and <video> elements”.
  • Firefox 7/7.0.1: “Drastically improved memory handling for certain use cases”.
  • Firefox 5: “Improved canvas, JavaScript, memory, and networking performance”.

The Firefox 7 and 15 mentions match the release announcements.  The Firefox 5 and 8 mentions are minor.

At this point it should be clear that this really is a misconception, with no basis in fact.

What Causes the Misconception?

My best guess is that Chris Peterson nailed it with this comment.

I think the press (overly) publicized the add-on leak fix as it progressed through Firefox’s 6-week release pipeline (Nightly -> Aurora -> Beta -> Release).

In other words, it’s caused by the combination of Firefox’s rapid release schedule and the current intense interest in browser development in the tech press.

For example, a random tech press reader may have heard about the Firefox 15 add-on leak fix multiple times on different sites:  on May 8 shortly after it first landed, then again on July 19 when it entered Beta, and then again on August 29 when it was released.  (These articles correspond to increasingly prominent blog posts from Mozilla employees and Mozilla itself, such as Kyle Huey’s personal blog, the Mozilla Web Developer Blog, and the official Mozilla Blog.)  If that reader wasn’t paying close attention, it’s easy to see how they could end up with this misconception.

It’s an interesting and difficult problem.  I think it’s reasonable for Mozilla employees and Mozilla to announce important changes multiple times, at different stages of development, on different communication channels.  I also think it’s reasonable for tech press sites to report important changes at different stages of development (especially when you consider that each individual site might only mention a change once or twice).  And I don’t think it’s realistic to expect readers to remember which in-development version of Firefox it was that contained some change that they read about two or three months ago.

My only idea for a solution is ad hoc education.  So, if you see someone holding this misconception, please point them at this article!  Even better, if you can determine how they came to believe it, please let me know.