Categories
about:memory add-ons Firefox Memory consumption MemShrink

MemShrink progress, week 38

After last week’s action, this week was quieter for MemShrink.

Add-ons

I mentioned last week the plan to test the top 100 add-ons for memory leaks.  Unfortunately we learned this week that the list I gathered is the top 100 installed add-ons, not the top 100 enabled add-ons.  It’s quite possible that a lot of installed “third-party” add-ons (those installed by a program outside of Firefox, such as anti-virus programs) are disabled, in which case this top 100 list won’t reflect actual usage.

As a result, the top 100 testing is on hold until we can resolve this issue.  Telemetry data may help, though that data might exhibit opt-in biases.  I’m also going to investigate the possibility of changing the daily ping to distinguish between enabled and disabled add-ons, which would give us fully representative data.

Landed patches

I merged the “dom+style” and “layout” trees in about:memory.  This is a step towards per-tab memory reporting.  It also probably breaks about:nosy 🙁

I also converted the DOM memory reporters to the new style, added measurement of URIs and links, and added measurement of the FramePropertyTable.  These changes reduced about:memory’s “heap-unclassified” by several MBs in common cases.

Bill McCloskey changed the GC marker stack so it shrinks periodically.  Previously it could grow from 256KB to over 2MB and would never be shrunk once that happened.

Bug counts

This week’s bug counts:

  • P1: 29 (-0/+1)
  • P2: 131 (-4/+6)
  • P3: 87 (-3/+7)
  • Unprioritized: 1 (-2/+1)
Categories
about:memory add-ons Firefox Garbage Collection Memory consumption MemShrink

MemShrink progress, week 37

It’s been a huge week for MemShrink.

Add-ons

I filed a bug on testing the top 100 add-ons for memory leaks.  The majority of these add-ons are not available on AMO and so are not subject to the leak checking done during AMO reviews.  The instructions and current test results are here.  Randell Jesup helped identify some some add-ons with unclear identities, and Nils Maier and Archaeopteryx have both tested several add-ons.  A month ago I said that add-ons that leak are the #1 problem for MemShrink, and this bug represents a huge step towards reducing that problem.  We’ll need lots of additional help to test this many add-ons, so please feel free to jump in!

As far as I know, comprehensive testing of the most popular add-ons has never been done before.  Although this testing is aimed at finding memory leaks, it’s quite possible it will uncover various other problems with add-ons.  Indeed, it’s clear just from looking at the list that quite a few of the non-AMO add-ons are of dubious merit, and this has stimulated some interesting discussion on dev-platform about third-party add-ons, i.e. those that are installed into Firefox by an external program.

The following add-ons had leaks fixed or mostly fixed by their authors: McAfee Site Advisor, Ghostery, Spool, Screengrab (fix version), Roboform, UF Comment Board ToolsGeenstijl, Long URL Please, HTML Desktop Notifications.

Nils Maier greatly improved the documentation on common causes of memory leaks in add-ons.  This was a MemShrink:P1 bug.  That doesn’t mean the document can’t be improved further, however;  it’s a wiki so please continue to add to it if you can.

Regression testing

John Schoenick’s excellent areweslimyet.com is getting close to being ready for a public unveiling.  The site is currently live but password-protected, simply to prevent large numbers of people accessing it before it’s ready.  (If you want a sneak peek, contact me for the password.)  More importantly, it identified a large regression in memory consumption caused by the landing of the JS engine’s incremental garbage collector on February 19, which Bill McCloskey is investigating.

Tim Taubert improved Firefox’s regression testing to ensure that no new DocShell and DOMWindow leaks are introduced.  This was a MemShrink:P1 bug because these leaks are quite easy to introduce.  Tim wrote some more about this change here.

Cycle collector

Jan Honza Odvarko’s about:ccdump add-on made it onto AMO this week.  Jan has been using this to hunt down some tricky leaks in Firebug.

Marco Bonardo fixed a leak in PlacesUtils.removeLazyBookmarkObserver() that I won’t pretend to understand, but which was a MemShrink:P1.  Marco also fixed a leak that occurred after bookmarking a page, closing the window, and opening a new window.

Olli Pettay fixed an equally impenetrable (to me) leak involving nsFormFillController::mFocusedInput.

Kyle Huey fixed a leak in the About Firefox dialog.

Andrew McCreight added additional information to cycle collector’s error console logging, which helps with identifying and debugging cycle collector problems.

Miscellaneous

Jason Duell fixed an obscure leak involve web sockets.

Bill McCloskey fixed a minor JS engine leak.

I added a new memory reporter called “js/runtime/gc-marker”.  It starts out at 256KB and I saw it reach 2.8MB when running MemBench.  I also converted the existing source image reporters to the new style, which seems to haved fixed some bogus results in about:memory as a side-effect.

Quote of the week

Adam Overa of Tom’s Hardware did another browser Grand Prix.  Devin Coldewey used the results from the Grand Prix to conclude that Firefox and Chrome are both great, and which you prefer basically comes down to a matter of taste.  While that is an interesting conclusion, what caught my eye was this comment, by Balaji Viswanathan:

I guess the title could have been “All browsers suck equally bad now”. Firefox and Chrome have grown to become more resources hogs – closer to IE. These days I shudder to fire up the firefox as the memory leaks are terrible. Two hours of Firefox with a Facebook tab is enough to gobble up 25% of my memory. With Chrome, I would have 20 rendering processes showing up when I would have just 3 tabs open.

In the first 2 years of Chrome I had probably 2 or 3 crashes. These days, it crashes every week or so. I long for the 2006 era Firefox – clean, simple and lean. Its been a long time since I have used IE actively and with Safari lesser said the better. For the developers, we have to deal with the ultra slow update cycles of IE and ultraspeed update cycles of Chrome. In short, we are getting worse and worse in the browser arena. The market is ripe for a breakthrough.

“2006 era Firefox” would have been Firefox 1.5 or Firefox 2.  Balaji may think he’s nostalgic for browsers of that era, but really he’s nostalgic for the web of that era, which was massively simpler than the web of today.  If Balaji tried Firefox 1.5 or Firefox 2 today — with no HTML5 support, no JavaScript JIT and no hardware acceleration — today, I’m sure he’d quickly decide that 2012-era browsers aren’t so bad after all.  I guess the interesting question is this: why do people blame browsers instead of websites for high resource consumption?

Bug counts

This week’s bug counts:

  • P1: 28 (-5/+5)
  • P2: 129 (-12/+7)
  • P3: 83 (-8/+12)
  • Unprioritized: 2 (-2/+2)

That’s a net reduction of one bug.  But more importantly, there is lots of movement, which is great!  It means that problems are being identified and fixed.

(Finally, commenters please note that I’ve turned on the WP-reCAPTCHA plug-in, and this the first post I’ve written since doing so.  In my testing it’s worked fairly well.  Hopefully it won’t cause problems.)

Categories
about:compartments about:memory add-ons compartments Firefox Memory consumption MemShrink

MemShrink progress, week 36

Lots of activity this week.

Leaky add-ons

I created a new devmo wiki page documenting common causes of memory leaks in add-ons.  I based this on a lovely selection of examples provided by Nils Maier.  Unfortunately, I know almost nothing about writing add-ons and so I’m not happy with the current state of the documentation.  I’ve taken it as far as I can, but it very likely has errors, leaves out important cases, conflates distinct concepts, and generally is not as good as it should be.  This documentation is really important — we have good tools for identifying when add-on leaks occur but we don’t yet have good tools for identifying their causes.  Until we have those tools, documentation is the only way we can help add-on authors fix leaks.  If someone who knows more about add-ons is willing to help please contact me!

Alexandre Poirot fixed a leak in the Add-on SDK that was causing zombie compartments when certain add-ons were disabled.  This also fixed bug 725603 and probably fixes some zombie compartments reported in some other add-ons (e.g. MemChaser).

Jan fixed several leaks in the Galaxytoolbar add-on.  The new version is 2.6.12.

A small number of add-ons have been found that disable Firefox’s XUL cache.  This is a recipe for disastrous performance, and so Matt Basta updated the AMO add-on validator to detect this.

Tools

I landed support for a new page called about:compartments. The exposure of zombie compartments in about:memory has become an extremely powerful leak detection tool.  But using about:memory to find zombies is non-trivial — there are multiple steps and ways to get it wrong.  The motivation for about:compartments is to make the detection of zombie compartments as simple as possible.  Here’s a screenshot:

about:compartments screenshot

Some things to note:

  • It only shows compartments, and all of them.
  • User compartments from web content (usually the interesting ones) are listed separately from system compartments.
  • The garbage and cycle collectors are automatically run when the page is loaded, ensuring that dead compartments aren’t listed.
  • The “More verbose” link at the bottom just causes the truncated URLs to be shown in full.
  • about:compartments shares a lot of code with about:memory.
  • I updated the documentation on zombie compartments accordingly.

Olli Pettay created about:cc, an add-on that can detect various kinds of document leaks relating to cycle collection.  Olli has already found several leaks with this tool.  Jan Honza Odvarko has written about:ccdump, a similar but prettier add-on.  I’m not certain but I think Olli and Jan are now co-ordinating their efforts.

I mentioned Mozilla QA’s MemChaser add-on a few weeks ago.  It lets you track memory usage and GC/CC activity easily via the add-on bar, and also allows logging of memory-related activities.  It’s now available on AMO, which guarantees you’ll receive updates as they’re released.

Jesse Ruderman tweaked his DOM fuzzer and found several new small leaks relating to nsITimers.  Jesse also modified about:memory so that it produces assertions that his fuzzer will catch.  This means that his fuzzer will detect if any memory reporters produce bogus values.

Miscellaneous

Kyle Huey fixed a zombie compartment that occurred when searching within pages with onclick handlers, which is a pretty common operation.

Jeff Muizelaar fixed a huge Mac-only leak relating to text rendering.  This was a recent regression that isn’t present in any released version of Firefox.

Josh Aas fixed a bug in cookie clearing — prior to Josh’s fix, if you cleared all cookies, Firefox would launch an instance of the plugin-container process for every plug-in installed, which could cause freezes and memory spikes.

Andrew Quartey updated the WebGL memory reporters to the new style.

Bug counts

This week’s bug counts:

  • P1: 28 (-1/+3)
  • P2: 134 (-6/+9)
  • P3: 79 (-8/+11)
  • Unprioritized: 2 (-1/+2)

Lots of movement there:  plenty of bugs fixed, but even more new ones.  Roughly 20 of the new ones fell into the following three categories.

  • Zombie compartments found in AMO add-ons by Kris Maglione and Andreas Wagner.
  • Leaks found by Olli Pettay’s new about:cc tool, mentioned above.
  • Leaks found by Jesse Ruderman’s tweaked DOM fuzzer, mentioned above.

This is a good thing!  It shows that new policies and tools are exposing existing problems.  I expect this higher level of new bug filing will continue for a couple of weeks.

Categories
about:memory add-ons Firefox Memory consumption MemShrink

MemShrink progress, week 35

Add-ons

Zombie compartments were fixed in the following add-ons:  Customize Your Web (fixed by Rudolf Noe), GridTube (fixed by Costas B.), Do Not Track Plus (fixed by kiran).

Marco Bonardo changed the Places JS services in a way that prevents certain kinds of SQLite connection leaks.  As far as I can tell, this fixes leaks in the Delicious Bookmarks and CyberSearch add-ons.

Finally, Alexandre Poirot fixed a bug in the Add-on SDK that was causing zombie jetpack compartments in some cases when add-ons were disabled.

Memory Reporting

Hugh Nougher added a memory reporter for GPU memory on Windows 7 and Vista.  See the “gpu-committed”, “gpu-dedicated” and “gpu-shared” entries in about:memory’s “Other Measurements” list.

I reduced the amount of memory allocated when generating about:memory by about 35%.

Miscellaneous

Josh Aas implemented unloading for out-of-process plug-ins.  If one is unused for 3 minutes it will be unloaded.

Andrew McCreight improved cycle collector dumping, which is useful in certain debugging cases.

Quote of the week

LifeHacker did some browser performance tests.  Firefox 10 handily won the memory usage test, which involved loading sites in 9 tabs and then measuring.  I personally think this is a pretty meaningless test, but I won’t complain about the good press.

As usual, the comments on the article featured a lot of debate about  whether Firefox is a memory hog or not.  One comment particular caught my attention:

They hardly used to be myths. I saw several times when old FF2x would be taking up over 1.4GB of RAM with just half a dozen tabs open.

Firefox 2 was released in October 2006, and superseded by Firefox 3 in June 2008.  Bad reputations are really difficult to shake.

Bug counts

This week’s bug counts:

  • P1: 26 (-0/+4)
  • P2: 131 (-6/+3)
  • P3: 76 (-2/+3)
  • Unprioritized: 1 (-2/+1)
Categories
about:memory add-ons Firefox Memory consumption MemShrink

MemShrink progress, week 34

Add-ons

The AMO add-on review checklist was amended a couple of weeks ago to include checks for zombie compartments.  This change is bearing fruit:  Andreas Wagner and Kris Maglione have found more than 10 submitted add-ons that have leaks.  See here, here, here, here, here.  With the experience they are gaining, we should be able to greatly improve the documentation on common causes of leaks.

In less positive news, two leaks were found in the add-on SDK.  Fortunately the SDK team has proven to be effective at fixing identified leaks quickly in the past, hopefully they’ll do so again!

Finally, Jason Tackaberry fixed a zombie compartment in NoSquint 2.1.2.  The fix is in the latest version (2.1.5).

about:nosy

Andrew Sutherland wrote a extension called about:nosy which is like about:memory on steroids.  It’s oriented around hiding many of the details and instead assigning blame for memory allocations to particular tabs (and similar things).  It also features graphs showing how the memory consumption of each tracked entity changes over time;  this latter feature is quite memory and CPU-intensive, however.  If you are running a recent Nightly build of Firefox, download about:nosy here and you won’t even have to restart Firefox to see it, just type “about:nosy” into the address bar.

Forthcoming changes will make about:memory more like about:nosy, by measuring more things on a per-tab basis.  And for a long time I have had a vague plan that one day someone who knows about UX will write a user-friendly alternative to about:memory that focuses just on per-tab memory consumption, and about:nosy is a good indicator of what that might look like.

Miscellaneous

Saptarshi Guha from the metrics team did an analysis of the physical memory consumption of Firefox 10, 11 and 12, based on telemetry data.  The post is heavy going for those who aren’t experts at statistics and R, but the two main conclusions of interest are (a) that add-ons significantly increase resident memory consumption, and (b) Firefox 12 is consuming more resident memory than Firefox 11.  This latter fact matches something we’d seen in today’s MemShrink meeting when looking at data from John Schoenick’s in-development version of areweslimyet.com — something in early January caused a significant memory consumption regression.  John is working on narrowing down which change caused this.

Gian-Carlo Pascutto overhauled the safe browsing implementation.  I don’t claim to understand this change at all, but I think it reduces memory consumption when the database is updated.  Better explanations from those who understand this change are welcome!

I reduced the amount of memory allocated when generating about:memory by roughly 30%.

I wrote a detailed discussion of the benefits of reducing memory consumption.

Bug Counts

Here are this week’s bug counts.

  • P1: 22 (-0/+0)
  • P2: 134 (-4/+8)
  • P3: 75 (-3/+4)
  • Unprioritized: 2 (-2/+1)
Categories
about:memory add-ons Firefox Memory consumption MemShrink

MemShrink progress, week 33

about:memory

Up until this week, about:memory was a static pages;  once generated, it couldn’t change.  This week, I landed a patch that makes every sub-tree expandable and collapsible.    This can be quite useful, because it gives you fine control over what details to ignore.  The following screenshot shows an example where all the level 1 sub-trees in the “explicit” tree are collapsed except for “startup-cache”.  (++ indicates sub-trees that can be expanded, -- indicates sub-trees that can be collapsed, and the remaining nodes (such as “heap-unclassified”) are leaf nodes).

a mostly-collapsed "explicit" tree in about:memory

I also changed about:memory so that obviously bogus values (e.g. negative values, percentages greater than 100%) are highlighted.  These indicate bugs in memory reporters, and so we want to know about them.

Memory Reporters

I added new memory reporters for style sheets.  This was the single biggest remaining chunk of dark matter.  On a 64-bit Linux build, this reduces the “heap-unclassified” count when I have Gmail and TechCrunch open from ~23% to ~15%.  The counts mostly show up under the “explicit/dom+style” sub-tree, in “style-sheets” leaf nodes.

I also simplified the writing of memory reporters by removing the need for the computedSize argument when measuring the size of a heap block.

Finally, if you create a sandbox with Components.utils.Sandbox, you can specify a name and about:memory will use that name to identify the sandbox’s compartment.  Sander van Veen made it so that sandboxes that aren’t given a name will use the  their callers’ filename as a name.  In other words, all sandboxes should now be identifiable in about:memory.

leaks

Brian Hackett fixed a leak in JaegerMonkey.

Andrew McCreight fixed a leak caused by watchpoints, which are used when debugging JavaScript code.

A leak related to JavaScript sharps (a non-standard, SpiderMonkey-only feature) was fixed by Jeff Walden when he removed support for sharps 🙂

Add-ons

I mentioned last week that I think leaky add-ons are the #1 problem for Firefox’s memory consumption, and mentioned the idea of telling users when they have an add-on installed that is known to have performance problems.  Bug 720856 is open for this.  Asa Dotzler, Firefox Product Manager, said:

I will secure Firefox client developer resources for this feature where I have some input into resourcing. If this plan is deemed appropriate, I will work with Justin to secure AMO side resources as well and we can nail this problem.

We can’t keep going back and forth on this while our users suffer. We must act now. I understand that defining “bad add-ons” will be contentious but so long as the technical approach is righteous we can sort out how heavy handed we want to be on policy at a later time and move forward implementing this today.

There was already a feature page covering this basic idea, and Asa updated it. This feature would be a huge help to users.  Fingers crossed we’ll see some progress soon!

Henrik Skupin has started working on an add-on called MemChaser (download it here) which is aimed at helping detect problems relating to memory consumption.  Currently it just shows some stats in the add-on bar — resident memory consumption (updated every two seconds), how long the last garbage collection took, and how long the last cycle collection took — but Henrik has many ideas for the future.  Worth watching!

Bug Counts

Here are this week’s bug counts.

  • P1: 22 (-0/+2)
  • P2: 130 (-3/+2)
  • P3: 74 (-2/+2)
  • Unprioritized: 3 (-4/+3)
Categories
about:memory AdBlock Plus add-ons Firefox Garbage Collection Memory consumption MemShrink

MemShrink progress, week 32

There wasn’t much MemShrink activity this week in terms of bugs fixed, just bug 718100 and bug 720359.  So I’m going to take the opportunity this week to talk about the bigger picture.

Bug Counts

As a prelude, here are this week’s bug counts.

  • P1: 20 (-4/+0)
  • P2: 131 (-3/+3)
  • P3: 74 (-2/+7)
  • Unprioritized: 4 (-3/+4)

The drop in P1s was just due to bug re-classification;  in particular, three bugs relating to long cycle collector pauses were un-MemShrink’d because they are more about responsiveness, and they are being tracked by Project Snappy.

The Big Ticket Items

David Mandelin asked me today what where the big ticket items for MemShrink.  I’d been looking a lot at the MemShrink:P1 list recently (which is why some were re-classified) and so I was able to break it down into six main areas that cover most of the P1s and various P2s.  I’ll list these from what I think is least important to most important.

#6: Better Script Handling

Internally, a JSScript represents (more or less) the code of a JS function, including things like the internal bytecode that SpiderMonkey generates for it.  The memory used by JSScripts is measured by the “gc-heap/scripts” and “script-data” entries in about:memory.

Luke Wagner did some measurements that showed that most (70–80%) JSScripts created in the browser are never run.  In hindsight, this isn’t so surprising — many websites load libraries like jQuery but only use a fraction of the functions in those libraries.  If SpiderMonkey could be changed to generate bytecode for scripts lazily, it could reduce “script-data” memory usage by 60–70%.  This would also allow the decompiler to be removed, which would be great.

Luke also proposed sharing immutable parts of scripts between web pages.  This would avoid a lot of duplication in the case where you have many tabs open with pages from a single site.

Both of these changes potentially will make the browser faster as well, because SpiderMonkey will spend less time compiling JavaScript source code to bytecode.

No-one is assigned to work on these bugs.  The lazy script creation can be done entirely within the JS engine;  the script sharing requires assistance from Necko.  Luke is currently busy with some other righteous refactorings, but I’m quietly hoping once they’re done he might find time for one or both of these bugs.

#5: Better Memory Reporting

Before you can reduce memory consumption you have to measure it.  about:memory is the critical tool that has facilitated much of MemShrink’s work.  (For example, we never would have known about zombie compartments without it.)  It’s in pretty good shape now but there are two major improvements that can be made.

First, the “heap-unclassified” number (a.k.a “dark matter”) is still typically around 20–25%.  My goal is to reduce that to 10%. This won’t require any great new insights, we already have the tools and data required.  Rather, it’s just a matter of grinding through the list of memory reporters that need to be added and improved.

Second, the resources used by each browser tab are reported in an unwieldy fashion:  JS memory on a per-compartment basis;  layout memory on a per-docshell basis;  DOM memory on a per-window basis.  Only a few internal architectural changes stand in the way of uniting these to provide the oft-requested feature of per-tab memory reporting.  This will be great for users, because if Firefox is using more memory than they’d like, it tells them which tabs they should close in order to free up memory.

I am actively working on both these improvements, and I’m hoping that within a couple of months they’ll be mostly done.

#4: Better Memory Consumption Tracking

One thing we haven’t done well in MemShrink is to improve the state of tracking Firefox’s memory consumption.  We have plenty of anecdotes but not much hard data about the improvements we’ve made, and we don’t have good ways to detect any regressions.  A couple of ideas haven’t gone very far, but some good news is that John Schoenick is making great progress on a proper areweslimyet.com implementation.  John has demonstrated preliminary versions of the site at two MemShrink meetings and it’s looking very promising.  It uses the endurance test framework to make the measurements, and opens lots of pages from the Talos tp5 pageset.

We also hope to use telemetry data to analyze how the memory consumption of each released version of Firefox stacks up.  That analysis would come with a significant delay — weeks or months after each release — but it would be much more comprehensive than any oft-run benchmark, coming from the real-world usage patterns of thousands of users.

#3: Compacting Generational GC

If you look in about:memory, JavaScript memory usage usually dominates.  In particular, the “js-gc-heap” is usually large.  There’s also the “js-gc-heap-unused-fraction” number, often 30% or higher, which tells you how much of that space is unused because of fragmentation.  That percentage overstates things somewhat, because often a good proportion of that unused space (see “js-gc-heap-decommitted”) is decommitted, which means that it’s costing nothing but address space… but that is cold comfort if you’re suffering out-of-memory aborts on Windows due to virtual memory exhaustion.

A compacting garbage collector is one that can move objects around the heap, filling up all those little gaps that constitute fragmentation.  The JS team (especially Bill McCloskey and Terrence Cole) is implementing a compacting generational garbage collector, which is a particular kind that tends to have good performance.  In particular, many objects die young and generational collectors find these quickly, which means that the heap will grow at a significantly slower rate than it currently does.  I could be wrong, but I’m convinced this will be a big win for both memory consumption and speed.

#2: Better Foreground Tab Image Handling

Images are stored in a compressed format (e.g. JPEG, PNG, GIF) on disk.  In order to display them, a browser must decompress (a.k.a decode) the compressed form into a raw pixel form that can easily be ten times larger.  This decoded form can be discarded and regenerated as necessary, and there are trade-offs to be made — for example, if you are too aggressive in discarding decoded images, you might have to decode them again, which will take CPU cycles and the user might see flickering if the decoding occurs in the visible part of the page.

However, Firefox goes way too far in the other direction.  If you open a page in the foreground tab, every single image in that page will be immediately decoded, and none of the decoded data will be discarded unless you switch away to another tab.  For pages that contain many images, this is a recipe for horrific memory consumption, and Firefox does much worse than all the other browsers.  So this is a problem that doesn’t rear its head for all users, but it’s terrible for those that are affected.

There are three MemShrink:P1 bugs relating to this:  one about not decoding all images immediately, one about discarding non-visible decoded images after some time, and one about some infrastructure work that is required for the first two.  As far as I know, no progress has been made on these three bugs, and although two of them are assigned they are not being actively worked on.

(See this discussion on the dev-platform mailing list for more details about this topic.)

#1: Better Detection and Notification of Leaky Add-ons

It’s been the case for several months that when a user complains about Firefox consuming an excessive amount of memory, it’s usually because of one or more add-ons, and the “can you try that again in safe mode?” / “oh yeah, that fixes it” dance is getting tiresome.

Many add-ons leak.  Even popular, well-written ones:  in the past few months leaks have been found in Adblock Plus, Video DownloadHelper, GreaseMonkey and Firebug.  That’s four of the top five add-ons on AMO!  We’re now getting several reports about leaky add-ons a week;  in this week’s MemShrink meeting there were four:  TorButton, NoSquint, Customize Your Web, and 1Password.  I strongly suspect the leaks we know about are just the tip of the iceberg.

Although leaks in add-ons are not Mozilla’s fault, they are Mozilla’s problem:  Firefox gets blamed for the sins of its add-ons.  And it’s not just memory consumption;  the story is the same for performance in general.  Here’s the quote of the week, from a user of 1Password:

I only use a handful of extensions and honestly never suspected 1P, however after disabling it I noticed my FireFox performance increased very noticibly. I’ve been running for 48 hours now without the 1P extension in Firefox and wow what a difference. Browsing is faster, switching is faster, memory usage is way down.

I’ve lost count of the number of stories like this that I’ve heard.  How many users have we lost to Chrome because of these issues, I wonder?

(And it’s not just leaks.  See this analysis of 16 add-ons and their effect on memory consumption when Firefox starts.)

One small step towards improving this situation was made this week:  Jorge Villalobos and Andrew Williamson added a “check for memory leaks” item to the AMO review checklist (under “Memory leaks from content”).  And Kris Maglione added some support for this checking in his Extension Test add-on.  This means that add-ons with obvious memory leaks (and many of them are obvious if you are actively looking for them) will not be accepted by AMO.

So that will prevents leaks in some new add-ons and new versions of established add-ons.  What about existing add-ons?  One idea is that AMO could also have a flag that indicates add-ons that have known memory problems (and other performance problems).  (This flag wouldn’t be an automatic thing, it would only be set once a leak has been confirmed, and after giving the author notification and some time to fix the problem.)  So that would also improve things a bit.

But lots of add-ons aren’t hosted on AMO.  Another idea is to have a stronger mechanism, one that informs the user if they have any add-ons installed that are known to cause high memory consumption (or other bad performance problems).  There is an existing mechanism for blocking add-ons that are known to be malware or exceptionally crashy, so hopefully the warnings could piggy-back on top of that.

Then, we need a better way to detect leaky add-ons.  Currently this is entirely done manually — and a couple of excellent contributors have found leaks on multiple add-ons — but I’m hoping that it’ll be possible to do a much more thorough job by analyzing telemetry data to find out which add-ons are correlated with high memory consumption.  That information could be used to trigger manual checking.

Finally, once you know an add-on leaks, it’s not always easy to work out why.  Tools could help a lot here, if they can be made to work well.

Conclusion

I listed six big areas for improvement. If we fixed all of these I think we’d be in a fantastic position.

Three of them (#5 better memory reporting, #4 better memory consumption tracking, #3 compacting generational GC) have people working on them and are in a good state.

Three of them (#6 better script handling, #2 better foreground image tab handling, #1 better detection and notification of leaky add-ons) don’t have people working on them, as far as I know.  If you are willing and have the skills to contribute to any of these areas, please contact me!

And if you think I’ve overestimated or underestimated the importance of any issue, I’d love to hear about it.  Thanks!

Categories
about:memory AdBlock Plus add-ons compartments DMD Firefox Garbage Collection JägerMonkey Massif Memory allocation Memory consumption MemShrink Performance SQLite Talks Valgrind

Notes on Reducing Firefox’s Memory Consumption

I gave a talk yesterday at the linux.conf.au Browser MiniConf, held in Ballarat, Australia.  Its title was “Notes On Reducing Firefox’s Memory Consumption”.

Below are the slides and notes in a SlideShare embedding. If you find that embedding problematic (some people do) you may prefer to download the PDF version directly.

Categories
about:memory AdBlock Plus add-ons compartments Firefox Memory consumption MemShrink

MemShrink progress, week 30

Add-ons

This was the week of add-ons in MemShrink-land.

Jared Wein fixed a problem in Firefox that was causing zombie compartments if you viewed a native video with any add-on installed that implements the nsIContentPolicy interface.  Examples of such add-ons are Adblock Plus, GreaseMonkey, and NoScript, which are respectively the #1, #3 and #9 most popular add-ons on AMO!  Welcome to the MemShrink club, Jared.

Speaking of GreaseMonkey, Arantius fixed a bug in it that was causing zombie compartments on some GM scripts when opening a background tabs.

I can’t tell who was responsible for the next fix, because the Add-on SDK folks use Github in a way I don’t understand.   But Myk Melez and/or Gabor Krizsanits greatly reduced the number of compartments used in JetPack-style add-ons.  In one example, the number of compartments dropped from 156 to 8, saving about 20MB of memory.  This was a MemShrink:P1 bug.

Also, as far as I can tell, the same patch also fixed bug 680821 which means that all compartments that hold sandboxes created by JetPack-style add-ons will be marked as belonging to that add-on in about:memory.

Jordan Miner reported that the Delicious Bookmarks add-on is leaking excessive numbers of connections to the Places database.  I tried to reproduce the problem and failed, but I don’t have a Delicious account.  If anyone else who does have a Delicious account is able to reproduce, please let me know or comment in the bug.

Finally, Jorge Villalobos and Andrew Williamson from the add-ons team came to this week’s MemShrink meeting.  We had a very fruitful discussion about how to help add-on authors detect and avoid memory leaks, and how to help add-on users understand which add-ons have high memory consumption.  Stay tuned for more details in the coming weeks!

Three Cheers for New Contributors

Krzysztof Kotlenga, a new contributor, removed an OpenGL cache that was wasting 1GB+ of memory on Linux when hardware acceleration was enabled (it’s currently not enabled by default, but will be at some point in the future).   Great work, Krzysztof!  [Update: I originally wrote WebGL instead of OpenGL, which was incorrect.]

Bug Counts

Here are the current bug counts.

  • P1: 26 (-2/+0)
  • P2: 132 (-14/+3)
  • P3: 67 (-2/+5)
  • Unprioritized: 4 (-0/+4)

That’s a net reduction of six bugs.  The main factor here was that I went through some of our P2s and closed ones that were stale and/or covered by other bugs, and downgraded to P3 a few more that are now known to be less important than we first thought.

Before finishing, I’d like to highlight bug 703427.  Richard Hipp, one of the SQLite developers, has a tiny patch that drastically reduces the amount of memory used by SQLite in Firefox — I ran with it for a while and my SQLite memory consumption dropped from ~15MB to less than 3MB.  The patch also causes a moderate speed drop, but it’s unclear if that speed drop is noticeable to Firefox.  We need someone who understands Firefox’s SQLite usage well to evaluate this patch so that Richard knows if it’s something that should go into a released version of SQLite as an option.  The bug is assigned to Marco Bonardo but he’s currently very busy.  Is there anyway else who knows enough about SQLite to take on this bug?

Categories
about:memory AdBlock Plus Firefox Memory consumption MemShrink

MemShrink progress, week 27

Adaptive Memory Behaviour

The biggest news this week was that Justin Lebar landed code to make Firefox’s memory consumption adaptive on Windows.  The code works by wrapping VirtualAlloc() and some similar OS-level allocation functions.  Each time memory is allocated, the amount of available virtual and physical memory is measured by the wrapper.  If either of those amounts are below a threshold, a memory pressure event is triggered, which causes numerous components within Firefox to take steps to reduce their memory consumption.

It might not sound like it, but this is a big deal, and it was a MemShrink:P1 bug.  Firefox runs on a huge variety of machines and devices, and trying to find one-size-fits-all heuristics for discarding regenerable data is a recipe for unhappiness somewhere.  Adaptive behaviour is much better.

The initial settings for this feature are conservative, and some tuning may be needed.

  • The threshold used for virtual memory is 128MB, i.e. if the amount of available virtual memory drops below 128MB a memory pressure event is triggered.  (This number can be changed in about:config via the “memory.low_virtual_memory_threshold_mb” setting.) Hopefully this will reduce the number of OOM crashes that occur on Windows.
  • The threshold used for physical memory is 0, which means that it is currently ignored.  (This number can be changed in about:config via the “memory.low_physical_mem_threshold_mb” setting.) The reason for ignoring it currently is that low physical memory may be caused by a program other than Firefox — we don’t want to start discarding data if Firefox is only using a small fraction of physical memory.  In the future we can probably do better here by triggering memory pressure events if the fraction of physical memory used by Firefox exceeds some threshold;  hopefully this will avoid paging when memory usage is high.
  • Memory pressure events are throttled so they aren’t sent more than once every 10 seconds.  (This number can be changed in about:config via the “memory.low_physical_memory_notification_interval_ms” setting.)  This prevents thrashing in cases where the memory pressure events don’t help reduce memory consumption.

Memory pressure events are also currently unevenly observed — plenty of data could be dropped that currently isn’t — so there is room for improvement there.

Finally, there’s another bug still open to add similar adaptive behaviour on Mac, Linux and Android.  Note also that memory pressure events are also triggered on Android when Firefox goes into the background.

Add-ons

There has been good news for add-ons:  the #1, #6 and #8 most popular add-ons on AMO have all recently seen some MemShrink-related improvements.

Adding memory reporters to add-ons is a really good thing to do, and I plan to write some documentation to encourage other add-on developers to follow suit.  However, if you are an add-on developer and are thinking of doing this, I need to stress one thing:  the reports must have KIND_OTHER so that they end up in the “Other Measurements” list in about:memory.  If they are put in the “explicit” tree, then some memory bytes may be counted twice (once by Firefox, once by the add-on) which will completely screw up about:memory’s results.

Memory Reporters

I landed several improvements to memory reporters.

Bug Counts

Here are the current bug counts.

  • P1: 26 (-2/+1)
  • P2: 139 (-6/+6)
  • P3: 64 (-2/+2)
  • Unprioritized: 0 (-1/+0)

Nice to see the total count drop, even if only by one.

Due to the Christmas break there won’t be a MemShrink meeting nor a MemShrink progress report next week.  I’ll be back in two weeks, enjoy the break!