You make what you measure

Inspired by Shaver’s patch, I implemented some per-compartment stats in about:memory.  I then visited TechCrunch because I know it stresses the JS engine.  Wow, there are over 70 compartments!  There are 20 stories on the front page.  Every story has a Facebook “like” button, a Facebook “send” button, and a Google “+1″ button, and every button gets its own compartment.

That sounds like a bug, but it’s probably not.  Nonetheless, every one of those buttons had an entry in about:memory that looked like this:

Old compartment measurements

(The ‘object-slots’ and ‘scripts’ and ‘string-chars’ measurements are also new, courtesy of bug 571249.)

Ugh, 255,099 bytes for a compartment that has only 971 bytes (i.e. not much) of scripts?  Even worse, this is actually an underestimate because there is another 68KB of tjit-data memory that isn’t being measured for each compartment.  That gives a total of about 323KB per compartment.  And it turns out that no JIT compilation is happening for these compartments, so all that tjit-data and mjit-code space is allocated but unused.

Fortunately, it’s not hard to avoid this wasted space, by lazily initializing each compartment’s TraceMonitor and JaegerCompartment.  With that done, the entry in about:memory looks like this:

New compartment measurements

That’s an easy memory saving of over 20MB for a single webpage.  The per-compartment memory reporters haven’t landed yet, and may not even land in their current form, but they’ve already demonstrated their worth.  You make what you measure.

27 Responses to You make what you measure

  1. When does this go into Firefox?

  2. Great to see examples of how we’re fighting the memory usage battle — keep it up!

  3. Holy Smokes! When does this land?

  4. @ Havvy, Mark:
    To follow along, check out:
    https://bugzilla.mozilla.org/show_bug.cgi?id=661068
    and
    https://bugzilla.mozilla.org/show_bug.cgi?id=665404

    They both have reviewed patches, but for you to see the changes, they’ll need to land on tracemonkey first, then on mozilla-central (at which point you’ll see the bug status change to fixed and a comment with the http://hg.mozilla.org/***mozilla-central***/rev/ commit message).

    After that (and depending on the time of day), it will be up to 24-28 hours before the change is present in the latest nightly: http://nightly.mozilla.org/

    Depending on which version of Firefox is listed as being in the nightly stage (https://wiki.mozilla.org/Releases) at the time of the patch landing, will determine which aurora/beta/release version of Firefox you can expect to see this in.

    If you are interested in following the memory leak/footprint reduction bugs in general, see:
    https://bugzilla.mozilla.org/show_bug.cgi?id=640457
    https://bugzilla.mozilla.org/show_bug.cgi?id=659860
    https://bugzilla.mozilla.org/show_bug.cgi?id=659858
    https://bugzilla.mozilla.org/show_bug.cgi?id=659857
    https://bugzilla.mozilla.org/show_bug.cgi?id=659855

    Hope that helps :-)

  5. I’m trying to get my head around the fact that a facebook like button uses as much memory as a Commodore 64 for mjit-code that doesn’t actually do anything…

    • Nicholas Nethercote

      Mardeg: the whole point is that it allocates the memory but doesn’t use it.

  6. Nicholas Nethercote

    Havvy, Mark: I landed the TraceMonitor change yesterday, I’ll land the JaegerCompartment change today. Barring disaster, they’ll be in Firefox 7 which will be out in about 3 months.

    I’m not sure when the per-compartment reporting will land, there’s some more work to do there.

    (Sorry for the slow reply; I tried replying 3 times yesterday and the comments were swallowed every time.)

  7. Awesome!

  8. Just curious what sort of slowdown there is not having those objects cached. Will I notice when I click something and there is a pause while it loads?

    • Nicholas Nethercote

      Jason: no slowdown. If anything you’d see a speed-up, because there are fewer allocations, but the effects will be far too small to notice.

  9. Sweet! Can’t wait for these memory fixes to land on m-c. =)

  10. Memory allocated but untouched is not committed to the process. In other words, this “fix” is a no-op. You shoul probably review this: varnish-cache.org/trac/wiki/ArchitectNotes and this: http://en.wikipedia.org/wiki/Virtual_memory

    • Nicholas Nethercote

      ivoras: tell that to the Windows users who get crashes because Firefox runs out of address space :P

  11. ivoras: You’re assuming it’s untouched, which is not necessarily the case if a bunch of objects have been instantiated. If it’s just “raw” memory that’s been allocated, then sure.

  12. Those sites need to just keep the like buttons and other crap on the actual article page. What in the hell is the point of loading up the first page with a ton of iframes?

  13. 255,099 – 2996 = 20,000.

    (sigh)

  14. If you care to test another news site with a heavyweight front page, you can look here: http://www.businessinsider.com/

    Might pop another rivet ;-) Thanks for the nice work.

  15. Will this be useful to identify memory problems with addons?

    Thanks for the work, anyway!

    • Nicholas Nethercote

      Rodze: in some cases. I think — but am not certain — add-ons that use the JetPack SDK are put in their own compartment, so they will be identifiable, but non-JetPack add-ons won’t be identifiable. I should check that out, thanks for the suggestion.

  16. Maybe this is not an issue for this specific page, but it may be for others: since most of these compartments are duplicates of the same buttons, isn’t it possible to share the same “JITted” code? This would save memory and the time for “re-JITting” the script.

    • Nicholas Nethercote

      Alexandre: sharing isn’t possible, AIUI. Each compartment has its own global object, and the JITted code that is produced depends on that global object. In other words, the code for two seemingly-identical compartments actually has different global object addresses hard-wired into it. My understanding is that removing this hard-wiring would hurt performance significantly. The good news is that overall, I think the memory savings that sharing JITted code would allow are small compared to easier memory savings that we can get elsewhere in the browser.

  17. John Haugeland: it is a savings of about (255,099 – 2,996) bytes per compartment (not kilobytes), but there are about 70 compartments on the TechCrunch webpage, due to all of the like buttons. That’s a total of about 20 megs (17647210 bytes by my math, but close enough).

  18. As a mainframe guy it’s nice to see the “breakdown usage and do something useful with it” idea being applied to Firefox memory. In https://www.ibm.com/developerworks/mydeveloperworks/blogs/MartinPacker/entry/memory_breakdown_in_firefox7?lang=en_us I point to this blog entry as an example of where it appears to have paid off nicely. I would echo the point that some have made that virtualreal memory usage but also see others have pointed out that virtual is still important in and of itself, and that virtual can sometimes lead to SOME real being used anyway. Of course, in my blog post, I point out this style of problem decomposition is something we can do using interval-based instrumentation – in z/OS. I wonder if Firefox can do the same – to see the time-driven pattern.