{"id":2395,"date":"2012-12-21T16:12:17","date_gmt":"2012-12-21T05:12:17","guid":{"rendered":"http:\/\/blog.mozilla.org\/nnethercote\/?p=2395"},"modified":"2012-12-21T16:12:17","modified_gmt":"2012-12-21T05:12:17","slug":"dmd","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/nnethercote\/2012\/12\/21\/dmd\/","title":{"rendered":"DMD"},"content":{"rendered":"<p>I recently landed a new version of DMD on mozilla-central.\u00a0 DMD is a tool helps us understand and thus reduce Firefox&#8217;s memory consumption.\u00a0 But in order to understand DMD, you first have to understand about:memory.<\/p>\n<h3>about:memory<\/h3>\n<p>The <a href=\"https:\/\/wiki.mozilla.org\/Performance\/MemShrink\">MemShrink project<\/a> started about 18 months ago, and it <a href=\"https:\/\/blog.mozilla.org\/nnethercote\/2011\/08\/09\/firefox-7-is-lean-and-fast-2\/\">has<\/a> <a href=\"https:\/\/blog.mozilla.org\/nnethercote\/2012\/07\/19\/firefox-15-plugs-the-add-on-leaks\/\">been<\/a> <a href=\"https:\/\/blog.mozilla.org\/nnethercote\/category\/memshrink\/\">very<\/a> <a href=\"https:\/\/bugzilla.mozilla.org\/buglist.cgi?list_id=5254912;resolution=FIXED;status_whiteboard_type=allwordssubstr;query_format=advanced;status_whiteboard=MemShrink;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED\">successful<\/a> in reducing Firefox&#8217;s memory consumption.\u00a0 about:memory is MemShrink&#8217;s not-so-secret weapon when it comes to understanding Firefox&#8217;s memory consumption.<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2012\/12\/am.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-2396\" title=\"about:memory screenshot\" alt=\"about:memory screenshot\" src=\"http:\/\/blog.mozilla.org\/nnethercote\/files\/2012\/12\/am.png\" width=\"742\" height=\"529\" srcset=\"https:\/\/blog.mozilla.org\/nnethercote\/files\/2012\/12\/am.png 742w, https:\/\/blog.mozilla.org\/nnethercote\/files\/2012\/12\/am-300x213.png 300w\" sizes=\"(max-width: 742px) 100vw, 742px\" \/><\/a><\/p>\n<p>about:memory has some wonderful characteristics:\u00a0 it provides literally thousands of measurements;\u00a0 it&#8217;s available in ordinary release builds;\u00a0 and it&#8217;s trivial to run (just type &#8220;about:memory&#8221; in the address bar).\u00a0 This means that non-expert users can easily provide developers with detailed measurements if they are having problems.<\/p>\n<p>However, about:memory has two shortcomings.\u00a0 First, it simply visualizes the data provided by the <em>memory reporter<\/em> infrastructure.\u00a0 The coverage provided by this infrastructure is good, but there are still some gaps.\u00a0 These gaps manifest primarily in the &#8220;heap-unclassified&#8221; number in about:memory, which represents all the heap allocations that the memory reporters didn&#8217;t cover.\u00a0 Unfortunately, about:memory can provide zero insight into what is within &#8220;heap-unclassified&#8221;.<\/p>\n<p>Second, it&#8217;s hard to verify.\u00a0 There&#8217;s no obvious way to tell if the numbers it gives are accurate (with a few exceptions;\u00a0 e.g. negative numbers are obviously wrong).\u00a0 We have established good practices for writing memory reporters (<a href=\"https:\/\/wiki.mozilla.org\/Memory_Reporting\">measure sizes, don&#8217;t compute then;\u00a0 traverse data structures rather than maintaining size counters<\/a>) that prevent most errors, but it&#8217;s still quite easy to accidentally count a block of memory twice.<\/p>\n<p>This is where DMD comes in.\u00a0 It helps with both the heap-unclassified and double-counting problems.<\/p>\n<h3>DMD version 1<\/h3>\n<p>I wrote <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=676724\">the first version of DMD<\/a> over a year ago.\u00a0 &#8220;DMD&#8221; is short for &#8220;dark matter detector&#8221;, because &#8220;heap-unclassified&#8221; memory is sometimes jokingly called &#8220;dark matter&#8221;.<\/p>\n<p>DMD works by intercepting all calls to malloc\/free\/etc.\u00a0 This lets DMD track extra information about every heap block, such as where it was allocated.\u00a0 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.<\/p>\n<p>With that in place, DMD knows how many times each heap block has been reported.\u00a0 So, after running the memory reporters, we can up each block into one of the following three groups.<\/p>\n<ul>\n<li>Blocks that haven&#8217;t been reported indicate gaps in existing memory reporters.\u00a0 They contribute to &#8220;heap-unclassified&#8221;.<\/li>\n<li>Blocks that have been reported once are good.<\/li>\n<li>Blocks that have been reported twice or more indicate defects in existing memory reporters.\u00a0 They cause some measurements in about:memory to be too high, and &#8220;heap-unclassified&#8221; to be too low.<\/li>\n<\/ul>\n<p>DMD presents its results in a sorted fashion that lists the unreported and twice-reported cases that are more important first.<\/p>\n<p>This first version of DMD was implemented as a Valgrind tool, and what&#8217;s more, it required a special, patched build of Valgrind to run.\u00a0 This meant it was difficult to set up, ran very slowly, and could only be used on Linux and Mac.\u00a0 Despite these shortcomings, it has proved itself extremely useful, helping us get &#8220;heap-unclassified&#8221; down greatly (on my Linux desktop machine it&#8217;s typically between 8 and 12%) and identifying several cases of double-counting.<\/p>\n<h3>DMD Version 2<\/h3>\n<p>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.\u00a0 Valgrind was overkill for these purposes &#8212; it&#8217;s capable of supporting much more invasive tools &#8212; and, furthermore, there were existing tools (e.g. trace-malloc) in the Mozilla codebase that did exactly these things.\u00a0 In other words, it would be possible to build a <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=717853\">new version of DMD<\/a> that integrated directly into the browser.<\/p>\n<p>Work on this new version stalled for a while, because the old one was working well enough.\u00a0 But then B2G&#8217;s <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=797189\">Operation Slim Fast<\/a> started, and it quickly became obvious that <a href=\"https:\/\/bugzilla.mozilla.org\/\/show_bug.cgi?id=798484\">&#8220;heap-unclassified&#8221; on B2G<\/a> was typically much higher than it was on desktop.\u00a0 This is primarily because B2G has lots of small processes, and so various unmeasured things that weren&#8217;t a big deal on desktop became much more significant on B2G.\u00a0 And DMD version 1 doesn&#8217;t work on B2G devices.<\/p>\n<p>So that provided the impetus to complete the new version.\u00a0 Mike Hommey finished his new <a href=\"http:\/\/glandium.org\/blog\/?p=2848\">replace-malloc infrastructure<\/a> recently, which helped greatly, and the new version of DMD landed on mozilla-central last week.\u00a0 The old version will <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=819819\">soon be retired<\/a>.<\/p>\n<p>DMD now works on Linux, Android, Mac, B2G, and is <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=819839\">just shy of working on Windows<\/a> (where Ehsan Akhgari has been making gradual progress).\u00a0 It&#8217;s also <em>much<\/em> faster, partly because it avoids the overhead of Valgrind, and partly because it now uses sampling.\u00a0 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;\u00a0 this sacrifices a moderate amount of accuracy for a large amount of speed.<\/p>\n<h3>Try it<\/h3>\n<p>about:memory is wonderful, and DMD is how we make about:memory better.\u00a0 There are now <a href=\"https:\/\/wiki.mozilla.org\/Performance\/MemShrink\/DMD\">detailed instructions on how to build DMD, run it, and interpret its output<\/a>.\u00a0 It&#8217;s quite easy now, requiring only minor changes to the usual build and run steps, and several people have already done it successfully.\u00a0 Please try it out, and help us further improve about:memory.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently landed a new version of DMD on mozilla-central.\u00a0 DMD is a tool helps us understand and thus reduce Firefox&#8217;s memory consumption.\u00a0 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&#8217;s memory consumption.\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,4557,30,4544,4546],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/2395"}],"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=2395"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/posts\/2395\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/media?parent=2395"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/categories?post=2395"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/nnethercote\/wp-json\/wp\/v2\/tags?post=2395"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}