{"id":2140,"date":"2012-07-11T14:57:49","date_gmt":"2012-07-11T03:57:49","guid":{"rendered":"http:\/\/blog.mozilla.org\/nnethercote\/?p=2140"},"modified":"2012-07-11T18:03:37","modified_gmt":"2012-07-11T07:03:37","slug":"memshrink-progress-week-55-56","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/nnethercote\/2012\/07\/11\/memshrink-progress-week-55-56\/","title":{"rendered":"MemShrink progress, week 55-56"},"content":{"rendered":"<h3>Memory Reporting<\/h3>\n<p>I changed things so that <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=687724\">JavaScript memory consumption for web content is reported on a per-tab basis<\/a>, as the following example shows.<\/p>\n<pre>\u2502\u00a0 \u251c\u2500\u2500\u2500\u25004,472,568 B (00.50%) -- top(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/, id=236)\/active\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u251c\u2500\u25004,192,640 B (00.47%) -- window(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/)\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u25001,979,112 B (00.22%) ++ js\/compartment(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/)\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u25001,607,216 B (00.18%) ++ layout\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u2500\u2500\u2500352,520 B (00.04%) \u2500\u2500 style-sheets\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u2500\u2500\u2500253,312 B (00.03%) ++ dom\r\n\u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500480 B (00.00%) \u2500\u2500 property-tables<\/pre>\n<p>All the major components of each tab&#8217;s memory consumption &#8212; JS, layout, style sheets, and DOM &#8212; are now reported on a per-tab basis.\u00a0 This is great, because it&#8217;s something that people have been requesting for\u00a0 years.\u00a0 However, the presentation is still intimidating.\u00a0 Consider the following excerpt from about:memory.<\/p>\n<pre>\u251c\u2500\u2500\u250018,288,696 B (16.43%) -- window-objects\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500\u25006,263,208 B (05.62%) ++ top(about:memory?verbose, id=6)\/active\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500\u25005,090,352 B (04.57%) ++ top(chrome:\/\/browser\/content\/browser.xul, id=1)\/active\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500\u25003,422,280 B (03.07%) ++ top(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/, id=17)\/active\/window(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/)\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500\u25003,178,432 B (02.85%) ++ top(chrome:\/\/global\/content\/console.xul, id=21)\/active\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500\u2500\u2500\u2500334,424 B (00.30%) ++ top(resource:\/\/gre-resources\/hiddenWindow.html, id=3)\/active\/window(resource:\/\/gre-resources\/hiddenWindow.html)<\/pre>\n<p>Among those <code>top(...)<\/code> entries are two browser tabs (one for www.mozilla.org, one for about:memory), two browser chrome windows (browser.xul is the main browser window, and console.xul is the error console window), and the hidden window which is always present.\u00a0 Firefox developers can easily understand this, and technically-inclined users may be able to guess what&#8217;s going on, but the average user will struggle.<\/p>\n<p>From a user&#8217;s point of view, the visible things they have control over (i.e. windows and tabs) should be better distinguished from everything else, and be shown with nicer names than &#8220;browser.xul&#8221;.\u00a0 But the architecture of Firefox&#8217;s internals doesn&#8217;t make this easy.\u00a0 I&#8217;ve made one <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=771426\">not-very-successful attempt<\/a> to improve this, and I&#8217;d love to hear suggestions from other Firefox devs on how to present this information better.<\/p>\n<p>(The step after that one is to present some kind of &#8220;tab manager&#8221; &#8212; a massively stripped-down variant of about:memory that ordinary users can understand.\u00a0 This would also require localization for all the languages that Firefox supports.\u00a0 One step at a time!)<\/p>\n<p>Finally, another memory reporting improvement happened:\u00a0 Andrew McCreight and I added <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=704623\">measurement of orphan DOM nodes<\/a>.\u00a0 These are DOM nodes that have been discarded by a page but are still accessible from JavaScript objects.\u00a0\u00a0 They were the biggest single remaining contributor to &#8220;heap-unclassified&#8221;.\u00a0 For example, when I hit the &#8220;update&#8221; button on about:memory I get 5MB of them (don&#8217;t worry, they go away when the garbage collector runs).\u00a0 Also, badly coded sites can create large numbers of them.\u00a0 So it&#8217;s a good thing to be able to measure, for both users and web developers.<\/p>\n<h3>Miscellaneous<\/h3>\n<p>Mihai Sucan fixed <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=770993\">a bad leak involving pages that use <code>window.console<\/code><\/a>.\u00a0 Multiple people reported that this caused Firefox&#8217;s memory consumption to balloon to multiple GB.\u00a0 This leak was introduced during the Firefox 15 development cycle, and the fix has been backported to the Aurora channel, which is where Firefox 15 currently resides.\u00a0 One notable thing about this fix is that the problem was quite easy to diagnose because about:memory clearly indicated that the ConsoleAPI.js compartment was responsible for most of the memory consumption.\u00a0 Without the fine-grained memory reporting that was enabled by <a href=\"http:\/\/bholley.wordpress.com\/2012\/05\/04\/at-long-last-compartment-per-global\/\">compartment-per-global<\/a>, that memory would have been reported in a generic &#8220;System Principal&#8221; compartment which would have made diagnosis <em>much<\/em> harder.<\/p>\n<p>Wladimir Palant fixed <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=764258\">an issue in AdBlock Plus that causes its memory consumption to slowly grow when viewing sites that repeatedly reset the src property of images, such as Mibbit<\/a>.\u00a0 (The fine-grained memory reporting enabled by compartment-per-global also made this diagnosis much easier.)\u00a0 This fix is in Adblock Plus 2.1.<\/p>\n<p>Alexandre Poirot fixed <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=764831\">a minor leak in the Add-on SDK<\/a>.<\/p>\n<p>I wrote about <a href=\"http:\/\/blog.mozilla.org\/nnethercote\/2012\/07\/09\/how-to-compare-the-memory-efficiency-of-web-browsers\/\">the difficulties of cross-browser memory comparisons<\/a>.<\/p>\n<h3>Bug Counts<\/h3>\n<p>Here are the current bug counts.<\/p>\n<ul>\n<li>P1: 20 (-3\/+0)<\/li>\n<li>P2: 90 (-3\/+6)<\/li>\n<li>P3: 102 (-6\/+2)<\/li>\n<li>Unprioritized: 2 (-0\/+0)<\/li>\n<\/ul>\n<p>A net reduction of seven bugs!<\/p>\n<h3>Update on The big ticket Items<\/h3>\n<p>In January, I described six &#8220;<a href=\"http:\/\/blog.mozilla.org\/nnethercote\/2012\/01\/25\/memshrink-progress-week-32\/\">big ticket items<\/a>&#8221; that needed tackling to improve Firefox&#8217;s memory consumption.\u00a0 Let&#8217;s look at how they&#8217;ve progressed since then.<\/p>\n<h4>#6: Better Script Handling<\/h4>\n<p>This had two parts.\u00a0 The first part was to <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=678037\">only generate bytecode for a function once it is run<\/a>.\u00a0 I&#8217;ve made a good chunk of progress towards and have it working on very simple examples.\u00a0 This has required a <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=750279\">great deal of refactoring of the SpiderMonkey front-end<\/a>.\u00a0 (The front-end is a hairy piece of code, so this is virtuous in and of itself.)\u00a0 There are still a couple of <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=753145\">other<\/a> <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=765956\">bugs<\/a> blocking it from further progress.\u00a0 I intend to return to continue on this once they are done.<\/p>\n<p>The second part was to <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=679942\">share immutable parts of scripts between web pages<\/a>.\u00a0 No progress has been made on this.<\/p>\n<p>So, overall, this item is about 25% done, and progress is still ticking along slowly.<\/p>\n<h4>#5: Better Memory Reporting<\/h4>\n<p>This one also had two parts.\u00a0 The first part was to <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=563700\">reduce about:memory&#8217;s \u201cheap-unclassified\u201d number (a.k.a \u201cdark matter\u201d) to typically 10%<\/a>.\u00a0 People such as Nathan Froyd and I have made good progress on this.\u00a0 It&#8217;s now occasionally below 10% (my current session shows 7.5%) but often is around 15%.\u00a0 That&#8217;s much better than the 20&#8211;25% we typically were getting at the start of the year, and it&#8217;s low enough that people rarely complain about it now.\u00a0 And we&#8217;re very much into the long tail now, so it&#8217;ll be hard to improve things much further.\u00a0 For the most part I don&#8217;t think we need to.<\/p>\n<p>The second part was to report memory in a per-tab fashion.\u00a0 As mentioned above, I just completed this, although the presentation is not as user-friendly as it could be.<\/p>\n<p>The per-tab reporting was enabled by compartment-per-global.\u00a0 Compartment-per-global also gives us much more insight into the memory consumption of Firefox&#8217;s own JavaScript code, and even some idea about add-on memory consumption, which was (to me) an unexpected bonus.\u00a0 Indeed, its usefulness was demonstrated by the two leak fixes mentioned above.<\/p>\n<p>So, overall, this item is about 80% done.\u00a0 Although there is still some work to be done, it has progressed enough that I will remove it from the &#8220;big ticket items&#8221; list.<\/p>\n<h4>#4: Better Memory Consumption Tracking<\/h4>\n<p>We can cross this item off the list, thanks to <a href=\"http:\/\/areweslimyet.com\/\">areweslimyet.com<\/a>.\u00a0 In January I also mentioned the idea of using telemetry for this, but we&#8217;ve found that telemetry results are so noisy that little (with <a href=\"http:\/\/jlebar.com\/2012\/5\/30\/A_ghost_story.html\">rare exceptions<\/a>) can be gleaned from it, so there&#8217;s not really anything to be done on that front.<\/p>\n<h4>#3: Compacting Generational GC<\/h4>\n<p>This is one of the two key SpiderMonkey performance features under development (the other being <a href=\"https:\/\/wiki.mozilla.org\/Platform\/Features\/IonMonkey\">IonMonkey<\/a>), and so people such as Terrence Cole, Steve Fink, Brian Hackett, and Bill McCloskey and actively working on it.\u00a0 Unfortunately, it&#8217;s a huge undertaking that requires rewriting many of SpiderMonkey&#8217;s internal and external APIs.\u00a0 If I had to guess I&#8217;d say it&#8217;s 25% complete, but that really is just a wild guess.\u00a0 I&#8217;ll be pleased if it is finished before the end of the year.<\/p>\n<h4>#2: Better Foreground Tab Image Handling<\/h4>\n<p>This is the big ticket item for which the least progress has been made. There&#8217;s a <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=689623\">single bug<\/a> that is blocking all the follow-on work.\u00a0 Both Timothy Nikkel and Jet Villegas have spent time working on it, but it has been a difficult nut to crack.\u00a0 Justin Lebar had a recent <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=689623#c64\">suggestion<\/a> for narrowing its scope slightly.\u00a0 I hope it&#8217;s a good suggestion, because I&#8217;m out of ideas on this one.<\/p>\n<h4>#1: Better Detection and Notification of Leaky Add-ons<\/h4>\n<p>This is the most satisfying item of the lot.\u00a0 I expected to make only grudging, piecemeal progress, but Kyle Huey&#8217;s <a href=\"http:\/\/blog.kylehuey.com\/post\/21892343371\/fixing-the-memory-leak\">fix to prevent zombie compartments<\/a> prevents the vast majority of add-on leaks, enough to declare victory and cross this item off the list.\u00a0 I&#8217;ll be writing more about this next week.<\/p>\n<h4>Summary<\/h4>\n<p>Three items (#1, #4, #5) have progressed enough that they can be removed from the list.\u00a0 Only one of these directly improved Firefox&#8217;s memory consumption;\u00a0 the other two were about better measuring and monitoring of memory consumption.<\/p>\n<p>The remaining items are about reducing memory consumption.\u00a0 Two of them (#3, #6) have a long way to go, but progress has been made and is ongoing.\u00a0 One item (#2) has made little progress and has stalled.<\/p>\n<h3>The New big ticket Items<\/h3>\n<p>Here&#8217;s my updated list of the most important things.<\/p>\n<h4>#5: Better Script Handling<\/h4>\n<p>As mentioned above, this has two parts: <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=678037\">lazy bytecode generation<\/a>, and the\u00a0 <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=679942\">sharing of immutable parts of scripts<\/a>.\u00a0 I intend to continue working on the first part.\u00a0 Once that&#8217;s done, it may turn out that the second part isn&#8217;t necessary;\u00a0 we&#8217;ll see.<\/p>\n<h4>#4: Regain compartment-per-global losses<\/h4>\n<p>The measurements on areweslimyet.com have been creeping up for the past two months.\u00a0 The major cause is compartment-per-global, which has lots of benefits (as mentioned above) but also increases memory consumption by a small-to-moderate amount across the board.\u00a0 This is because there are many more compartments than there used to be, and there&#8217;s a certain amount of overhead and waste in each compartment.<\/p>\n<p>Generational GC will help, but there are some other things that can be done more quickly that will help.\u00a0 See the <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=764220\">tracking bug<\/a> for one example.<\/p>\n<h4>#3: Boot2Gecko<\/h4>\n<p>Boot2Gecko (now officially known as &#8220;Firefox OS&#8221;) is going to be running on low-end phones without much physical memory, so that&#8217;ll require care.\u00a0 The first step is to <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=767191\">get about:memory working on B2G<\/a>.\u00a0 The next step is to find a way to <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=768470\">copy the data from about:memory somewhere else<\/a>, because B2G doesn&#8217;t have cut and paste!\u00a0 Beyond that, it&#8217;s unclear;\u00a0 but once about:memory is working it&#8217;s very likely it will identify some sub-optimal B2G-specific behaviour.<\/p>\n<h4>#2: Compacting Generational GC<\/h4>\n<p>Let me <a href=\"https:\/\/blog.mozilla.org\/nnethercote\/2012\/02\/08\/the-benefits-of-reducing-memory-consumption-2\/\">quote myself<\/a> to explain the memory consumption benefits of compacting, generational GC.<\/p>\n<blockquote><p>Virtual memory consumption drops in two ways.\u00a0 First, the compaction minimizes waste due to fragmentation.\u00a0 Second, the heap grows more slowly.\u00a0 Physical memory consumption drops for the same two reasons.<\/p><\/blockquote>\n<p>The performance benefits are also significant.<\/p>\n<blockquote><p>Performance improves for three reasons.\u00a0 First, paging is reduced because of the generational behaviour:\u00a0 much of the JS engine activity occurs in the nursery, which is small;\u00a0 in other words, the memory activity is concentrated within a smaller part of the working set.\u00a0 Second, paging is further reduced because of the compaction: this reduces fragmentation within pages in the tenured heap, reducing the total working set size.\u00a0 Third, the tenured heap grows more slowly because of the generational behaviour&#8230; which means that structure traversals done by the garbage collector (during full-heap collections) and cycle collector are faster.<\/p><\/blockquote>\n<p>Important stuff.<\/p>\n<h4>#1: Better Foreground Tab Image Handling<\/h4>\n<p>On image-heavy pages, Firefox uses much more memory than other browsers.\u00a0 This includes things like Facebook image slideshows.\u00a0 One commenter <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=689623#c63\">said<\/a> the following.<\/p>\n<blockquote>\n<p id=\"comment_text_63\">On behalf of Facebook Inc, let me just say that we are prepared to give over one thousand free &#8220;pokes&#8221; to anyone who fixes this bug or alternatively <a title=\"REOPENED - We won't discard any images on the current tab even if they are not in the DOM\" href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=683290\">https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=683290<\/a>. I will also gladly show you Mark Zuckerberg&#8217;s desk and give you free dinner and cookies as part of a complementary tour of Facebook HQ in Menlo Park.<\/p>\n<\/blockquote>\n<p>I have no idea if this person is really from Facebook, but it&#8217;s certainly suggestive.\u00a0 Also, I&#8217;ve heard from B2G people that they are having to work around this problem in their Gallery app.<\/p>\n<p>To repeat myself from week 32:\u00a0 there are three MemShrink:P1 bugs relating to this:\u00a0 one about <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=542158\">not decoding all images immediately<\/a>, one about <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=661304\">discarding non-visible decoded images after some time<\/a>, and one about <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=689623\">some infrastructure work<\/a> that is required for the first two.\u00a0 (See <a href=\"https:\/\/groups.google.com\/forum\/#%21topic\/mozilla.dev.platform\/9JZhTxGlG8k\/discussion\">this discussion<\/a> on the dev-platform mailing list for more details about this topic.)<\/p>\n<h4>Summary<\/h4>\n<p>There are three repeat items, and two new items, but there are fewer items than last time;\u00a0 this reflects the fact that we are in a better position than we were in January.\u00a0 If you think I&#8217;ve overestimated or underestimated the importance of any of these, or omitted anything, I&#8217;d be interested to hear.<\/p>\n<p>One final thing:\u00a0 last time, several people suggested &#8220;better reporting of add-on memory consumption&#8221;.\u00a0 If I knew of any ideas on how to do this better than about:memory currently does, I&#8217;d gladly put it on the list.\u00a0 But I don&#8217;t, and there doesn&#8217;t seem to be much point to put an item on the list that we don&#8217;t know how to implement.<\/p>\n<h3>Vacation<\/h3>\n<p>I&#8217;m taking the next two weeks as vacation, so there won&#8217;t be a MemShrink report on July 24.\u00a0 I&#8217;ll be back with the next MemShrink round-up on August 8th.\u00a0 See you then.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Memory Reporting I changed things so that JavaScript memory consumption for web content is reported on a per-tab basis, as the following example shows. \u2502\u00a0 \u251c\u2500\u2500\u2500\u25004,472,568 B (00.50%) &#8212; top(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/, id=236)\/active \u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u251c\u2500\u25004,192,640 B (00.47%) &#8212; window(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/) \u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u25001,979,112 B (00.22%) ++ js\/compartment(http:\/\/www.mozilla.org\/en-US\/firefox\/fx\/) \u2502\u00a0 \u2502\u00a0\u00a0\u00a0 \u2502\u00a0 \u251c\u2500\u25001,607,216 B (00.18%) ++ layout \u2502\u00a0 [&hellip;]<\/p>\n","protected":false},"author":139,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4550,119,30,4555,4544,4546],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/2140"}],"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=2140"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/2140\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/media?parent=2140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/categories?post=2140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/tags?post=2140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}