{"id":991,"date":"2011-07-06T11:49:06","date_gmt":"2011-07-06T00:49:06","guid":{"rendered":"http:\/\/blog.mozilla.org\/nnethercote\/?p=991"},"modified":"2011-07-06T12:31:55","modified_gmt":"2011-07-06T01:31:55","slug":"memshrink-progress-week-3","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/nnethercote\/2011\/07\/06\/memshrink-progress-week-3\/","title":{"rendered":"MemShrink progress, week 3"},"content":{"rendered":"<p>This was the final week of development for Firefox 7, and lots of exciting MemShrink stuff happened.<\/p>\n<h3>Per-compartment memory reporters<\/h3>\n<p>I landed <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=661474\">per-compartment memory reporters<\/a>, using the new <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=666075\">memory multi-reporter interface<\/a>.\u00a0 I&#8217;ve <a href=\"http:\/\/blog.mozilla.org\/nnethercote\/2011\/06\/21\/you-make-what-you-measure\/\">written previously<\/a> about per-compartment reporters;\u00a0 the number of things measured has increased since then, and each compartment now looks like this:<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-992\" title=\"Screenshot\" src=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot.png\" alt=\"Output of a per-compartment memory reporter\" width=\"778\" height=\"328\" srcset=\"https:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot.png 778w, https:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot-300x126.png 300w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><\/p>\n<p>One nice thing about this feature is that it gives technically-oriented users a way to tell which web sites are causing high memory usage.\u00a0 This may help with perception, too;\u00a0 people might think &#8220;geez, Facebook is using a lot of memory&#8221; instead of &#8220;geez, Firefox is using a lot of memory&#8221;.<\/p>\n<p>Another nice thing is that it can help find leaks.\u00a0 If you close all your tabs and some compartments are still around, that&#8217;s a leak, right?\u00a0 Actually, it&#8217;s more complicated than that:\u00a0 compartments are destroyed by the garbage collector, so there can be a delay.\u00a0 But there are buttons at the bottom of about:memory which force GC to occur, so if you press them and some compartments are still around, that&#8217;s a leak right?\u00a0 Well, it appears that sites that use timers can stick around while the timers are still live.\u00a0 For example, <a href=\"http:\/\/tbpl.mozilla.org\/\">TBPL<\/a> appears to have a refresh timer that is 2 or 3 minutes long, so it&#8217;s compartment <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=668871\">stays alive<\/a> for that long after the page is closed.\u00a0 (Actually, it&#8217;s not entirely clear if or why that should happen.)\u00a0 However, once you&#8217;ve accounted for these complications, any remaining compartments are likely to have leaked.<\/p>\n<p>Another thing to note is that the JS heap space used by each compartment is now reported.\u00a0 Also, the fraction of the JS heap that isn&#8217;t currently used by any particular compartment is also reported:<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot-1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-993\" title=\"Screenshot-1\" src=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot-1.png\" alt=\"Output of non-compartment GC memory reporters\" width=\"469\" height=\"38\" srcset=\"https:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot-1.png 469w, https:\/\/blog.mozilla.org\/nnethercote\/files\/2011\/07\/Screenshot-1-300x24.png 300w\" sizes=\"(max-width: 469px) 100vw, 469px\" \/><\/a><\/p>\n<p>Once this change landed, it didn&#8217;t take long to see that the &#8220;gc-heap-chunk-unused&#8221; number could get very large.\u00a0 In particular, if you browsed for a while, then closed all tabs except about:memory, then triggered heap minimization (via the buttons at the bottom of about:memory), you&#8217;d often see very large &#8220;gc-heap-chunk-unused&#8221; numbers.\u00a0 It turns out this is caused by fragmentation.\u00a0 The JS heap is broken into 1MB chunks, and often you&#8217;d end up with with a lot of almost-empty chunks, but they&#8217;d have a small number of long-lived objects in them keeping them alive, and thus preventing them from being deallocated.<\/p>\n<h3>Reduced JavaScript heap fragmentation<\/h3>\n<p>Fortunately, Gregor Wagner had already anticipated this, and he tightened his grasp on the 2011 MemShrink MVP award by<a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=666058\"> greatly reducing this fragmentation in the JavaScript heap<\/a>.\u00a0 Parts of Firefox itself are implemented in JavaScript, and many objects belonging to Firefox itself (more specifically, objects in the &#8220;system principal&#8221; and &#8220;atoms&#8221; compartments) are long-lived.\u00a0 So Gregor added simple chunk segregation;\u00a0 objects belonging to Firefox get put in one group of chunks, and all other objects (i.e. those from websites) get put in a second group of chunks.\u00a0 This made a huge difference.\u00a0 See <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=666058#c31\">this comment<\/a> and subsequent comments for some detailed measurements of a short browsing session;\u00a0 in short, the size of the heap was over 5x smaller (21MB vs. 108MB) after closing a number of tabs and forcing garbage collection.\u00a0 Even if you don&#8217;t force garbage collection, it still helps greatly, because garbage collection happens periodically anyway, and longer browsing sessions will benefit more than shorter sessions.<\/p>\n<p>This change will help everyday browsing a lot.\u00a0 It will also help with the perception of Firefox&#8217;s memory usage &#8212; once you learn about about:memory, an obvious thing to try is to browse for a while, close all tabs, and see what the memory usage looks like.\u00a0 Prior to this patch, the memory usage was often much higher than it is on start-up.\u00a0 With this patch, the usage is much closer to the usage seen at start-up.\u00a0 Ideally, it would be the same, and Justin Lebar opened <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=668809\">a bug<\/a> to track progress on exactly this issue.<\/p>\n<p>There&#8217;s still room for reducing fragmentation in the JavaScript heap further.\u00a0 Kyle Huey has some good ideas in <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=669245\">this bug<\/a>.<\/p>\n<h3>Other bits and pieces<\/h3>\n<ul>\n<li>Chris Pearce finished a <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=592833\">major refactoring of media code<\/a>.\u00a0 Previously, every media (&lt;audio&gt; and &lt;video&gt;) element in a page required three threads (four on Linux).\u00a0 And each thread has a stack.\u00a0 On Linux, the stack is 8MB, on Windows it&#8217;s 1MB, on Mac it&#8217;s 64KB.\u00a0 (<strong>Edit:<\/strong> Robert O&#8217;Callahan pointed out in the comments that this space is not necessarily committed, which means they&#8217;re not really costing anything other than virtual memory space.)\u00a0 Webpages can have dozens, even hundreds of media elements, so these stacks can really add up.\u00a0 Chris changed things so that each media element has a single thread.\u00a0 This really helps on complicated web sites\/apps like <a href=\"http:\/\/thewildernessdowntown.com\/\">The Wilderness Downtown<\/a>, <a href=\"http:\/\/www.ro.me\/\">ROME<\/a>, and <a href=\"http:\/\/code.google.com\/p\/quake2-gwt-port\/\">WebGL Quake<\/a>.\u00a0 (There is also a <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=664341\">bug open<\/a> to reduce the thread stack size on Linux;\u00a0 8MB is excessive.)\u00a0 Chris only just landed these patches on mozilla-inbound, he deliberately waited until after the FF7 deadline to maximize testing time.\u00a0 Assuming there are no problems, this improvement will be in FF8.<\/li>\n<li>Jesse Ruderman tweaked some of his fuzzing tools to look for leaks and found <a href=\"https:\/\/bugzilla.mozilla.org\/buglist.cgi?quicksearch=669096%2C669105%2C669110%2C669240&amp;list_id=674223\">four new ones<\/a>.<\/li>\n<li>Mounir Lamouri landed some <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=663271\">memory reporters for the DOM<\/a>.\u00a0 They&#8217;re currently disabled while he extends them and makes that they&#8217;re reporting sensible numbers.<\/li>\n<li>I created <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=669241\">mlk-fx8<\/a>, a bug for tracking leaks and quasi-leaks reported against Firefox 8.<\/li>\n<\/ul>\n<h3>Quantifying progress<\/h3>\n<p>I&#8217;m going to attempt to quantify MemShrink&#8217;s progress in these weekly reports.\u00a0 It&#8217;s not obvious what&#8217;s the best way to do this.\u00a0 The <a href=\"https:\/\/wiki.mozilla.org\/Performance\/MemShrink#areweslimyet.com\">MemShrink wiki page<\/a> discusses this a bit.\u00a0 I&#8217;m going to do something crude:\u00a0 just count the number of bugs annotated with &#8220;MemShrink&#8221;, and track this each week.\u00a0 Here are the current counts:<\/p>\n<ul>\n<li>P1: 18<\/li>\n<li>P2: 44<\/li>\n<li>P3: 25<\/li>\n<li>Unprioritized: 2<\/li>\n<\/ul>\n<p>Obviously, this is a flawed way to measure progress;\u00a0 for example, if we improve our leak-detection efforts, which is a good thing, we&#8217;ll get more bug reports.\u00a0 But hopefully these numbers will trend downwards in the long term.<\/p>\n<p>I&#8217;m also wondering if my choice to have three priority levels was a mistake, if only for the reason that people like to pick the middle item, so P2 will always dominate.\u00a0 If we had four priority levels, we&#8217;d be forced to prioritize all those middling bugs up or down.<\/p>\n<p>The minutes of today&#8217;s meeting are available <a href=\"https:\/\/wiki.mozilla.org\/Performance\/MemShrink\/Meetings\/2011-07-05\">here<\/a>.\u00a0 Thanks to Jesse for taking them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This was the final week of development for Firefox 7, and lots of exciting MemShrink stuff happened. Per-compartment memory reporters I landed per-compartment memory reporters, using the new memory multi-reporter interface.\u00a0 I&#8217;ve written previously about per-compartment reporters;\u00a0 the number of things measured has increased since then, and each compartment now looks like this: One nice [&hellip;]<\/p>\n","protected":false},"author":139,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30,4544,4546],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/991"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/users\/139"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/comments?post=991"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/991\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/media?parent=991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/categories?post=991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/tags?post=991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}