Apr 5, 2014

Draft - Debug Firefox memory leak

Last week Kyle Huey gave a talk about debugging memory leak, this's the note I took, still in draft, will complete it later. Check also Kyle's blog for the same topic.

# Get a debug build Firefox
  $ hg clone https://hg.mozilla.org/mozilla-central
  $ cd mozilla-central
  $ ./mach bootstrap
  $ echo 'ac_add_options --enable-debug' > mozconfig
  $ ./mach build

# Used bug 847138 as an example. Open the test case i.svg, close it. Open
  another tab for about:memory, minimize memory usage, and measure can see the
  leak:

  ├──0.37 MB (00.32%) -- top(none)/detached/window(file:///home/ting/w/fx/i.svg)
  │  ├──0.35 MB (00.31%) ++ js-compartment(file:///home/ting/w/fx/i.svg)
  │  ├──0.01 MB (00.01%) ++ dom
  │  ├──0.01 MB (00.01%) ── style-sheets
  │  └──0.00 MB (00.00%) ── property-tables

# Save GC & CC logs from about:memory
  < cc-edges.xxxxx.xxxxxxxxxx.log >
    > 0x7f3852047100 globalE
    0x7f3852047100 [gc] JS Object (SVGZoomEvent)
    > 0x7f385202a220 type_proto
    > 0x7f385204dbc0 getter
    > 0x7f386ae43240 parent
    > 0x7f385d9f6c10 UnwrapDOMObject(obj)
    0x7f385d9f6c10 [rc=1] Event
    > 0x7f385d74d000 mPresContext
    > 0x7f3851df1800 mOwner
    > 0x7f3859d09800 mView

  < gc-edges.xxxxx.xxxxxxxxxx.log >
    > 0x7f3852047100 G globalE
    0x7f38556cbd20 B string globalE

# $ git clone https://github.com/amccreight/heapgraph.git
  $ cd heapgraph
  $ python find_roots.py /tmp/cc-edges.11209.1396360888.log nsDocument | less

  0x7f385d7fbce0 [nsISVGPoint]
      --[Preserved wrapper]--> 0x7f3852047140 [JS Object (SVGPoint)]
      --[type_proto]--> 0x7f385202a250 [JS Object (SVGPointPrototype)]
      --[getter]--> 0x7f385204dcc0 [JS Object (Function - y)]
      --[parent]--> 0x7f386ae43240 [JS Object (Window)]
      --[document]--> 0x7f3852047040 [JS Object (SVGDocument)]
      --[UnwrapDOMObject(obj)]--> 0x7f385d74c000 [nsDocument normal ([none]) file:///home/ting/Desktop/i.svg]

      Root 0x7f385d7fbce0 is a ref counted object with 1 unknown edge(s).
      known edges:
         0x7f3852047140 [JS Object (SVGPoint)] --[UnwrapDOMObject(obj)]--> 0x7f385d7fbce0
 
  < cc-edges.xxxxx.xxxxxxxxxx.log >
    0x7f385d7fbce0 [known=1]
    0x7f385d7fbce0 [rc=2] nsISVGPoint
    > 0x7f3852047140 Preserved wrapper
    0x7f3852047140 [gc] JS Object (SVGPoint)
    > 0x7f385202a250 type_proto
    > 0x7f386ae43240 parent
    > 0x7f385d7fbce0 UnwrapDOMObject(obj)

# $ python ./tools/heapgraph/find_roots.py ./gc-edges.3131.1396402800.log SVGZoomEvent | less

  via Preserved wrapper :
  0x7f3852047140 [SVGPoint ]
      --[shape]--> 0x7f385204ee98 [shape]
      --[base]--> 0x7f385204f628 [base_shape]
      --[parent]--> 0x7f386ae43240 [Window 7f385b5f4260]
      --[globalE]--> 0x7f3852047100 [SVGZoomEvent ]

  Found and displayed 1 paths.
  via Preserved wrapper :
  0x7f3852047140 [SVGPoint ]
      --[shape]--> 0x7f385204ee98 [shape]
      --[base]--> 0x7f385204f628 [base_shape]
      --[parent]--> 0x7f386ae43240 [Window 7f385b5f4260]
      --[globalE]--> 0x7f3852047100 [SVGZoomEvent ]
      --[type]--> 0x7f385203e8c8 [type_object]
      --[type_proto]--> 0x7f385202a220 [SVGZoomEventPrototype ]

  Found and displayed 1 paths.