Closed Bug 863228 Opened 11 years ago Closed 9 years ago

Implement a memory debugging panel

Categories

(DevTools :: Memory, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 933006

People

(Reporter: ochameau, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

Debugging memory leaks due to some references being kept in javascript is a really hard task in Firefox as there is very few tools to do that. No matter if it's a chrome or content leak.
We should provide tools for firefox contributors and/or web developers to figured out *if* and *why* firefox or a webpage leak.

I've been working on various way to walk throuh the CC graph in order to do that at both chrome and content level. 
I've attached the prototype addon I have that already proved its usefullness when we have to chase chrome leaks highlighted by increasing CC optimized list.
(you know these various leaks reported by :smaug ;))

I think we are not far from a very usefull and daily usable tool.
It currently displays too many view, but allows to see why ones will be usefull for what/who. I think firefox contributors and web developers will most likely want different views of the allocated objects.

Here is a description of this addon features:

### Tracked objects:

An tracking API is exposed to all webpages via a global object named `mem`
and to chrome via `Services.mem`. This API expose a `track` method that accept an object and allows to see if and why this object is still allocated at anytime. You can see the list of all tracked object in the "Tracked objects" panel.

Web page example:
<script>
  var foo = {}
  document.addEventListener("load", function onload() {
    foo;
  });
  mem.track(foo);
</script>

The tracked objects panel will tell you that your foo object is kept alived by the onload function, which appears to set as a DOM event listener to document. (it doesn't know which kind of event it was registered for)

Chrome example:
  const foo = {bar: {}};
  Services.mem.track(foo.bar);
Again, the tracked objects panel should tell you that your object is kept alive by an object refering to your object with "bar" property name.


### Snapshots
The same API also expose a "snap" method that also work both in chrome and content and this time allows you to take snapshots of the CC graph.
In its current state, it is focused to provide the list of allocated object between two precise snapshots.
So you have to call this method twice to get the list of allocated object between these two call.
This method is asynchronous, as it has to force some collection cycle to avoid reporting object that would have eventually be collected.
So that it returns a promise-like object.

Content example:
<script>
  mem.snap().then(function () {
    window.foo = {};
    mem.snap();
  });
</script>
You will find in Snapshot panel your result showing that you allocated a JS Object referenced from a Window via a "foo" attribute. (It will most likely also report some other internal objects)

Chrome example:
  var global = this;
  Services.mem.snap(this).then(function () {
    global.foo = {};
    Services.mem.snap();
  });
This time, you have to pass your global object to snap method. For internal reason, we require this as we need to know on which compartment we have to do the snapshot.

### Dead wrappers
This tool is only for firefox and addons developers. It allows you, at any time, to see if there is some dead wrappers being alive. It allows you to identify if there is some residual objects being still alive that refer to a nuked compartment. Typically, if you kept reference to a tab document that has been closed. We won't leak the tab document anymore, but still leak substantial amount of JS object in chrome/addon compartment.

### CC list
Simply returns the list of FragmentOrElement object being in the optimized CC list. You can already fetch this list by manually looking at the about:cc list. But here it is immediatly filtered and you can also walk through the graph and have a more readable output.

### CC JS list
This is very similar to CC list, but instead of listing FragmentOrElement, we list the first JS Objects owning directly or indirectly one of these FragmentOrElement. We then filter this list of JS Object again and remove the ones being owned by any other one of the list.
It is a really handy way to know if a FragmentOrElement object is kept alive by a JS object and why/how.


From my experience, CC lists doesn't seems usefull for web developers. And also appear to be reporting various false positive leaks. So these list should be kept for experienced people.
Tracked oject and snapshots are super handy, easy to grok and works especially well if you have some suspicious code in mind.


Then, when I exposed my early work, I was using a lot of jsctypes code that can reasonably used for production tool. The good news is that I'm only using it for two very precise features, so we could easily drop the ctypes code:
- for knowing if a given CC object is a dead wrapper (calls JS_IsDeadWrapper)
- to stringify function in order to ease understanding scope leaks (calls JS_DecompileFunction and various other jsapi functions)


So, if you feel like me that we aren't that far from a production tool and that we can allocate some resources to ship that in the product, I already have a list of feature request to tune the platform in order to have a sane and effective implementation. (It currently always go throught the whole CC graph!)
Attached file The prototype addon
Blocks: 723783
Flags: needinfo?(dcamp)
There is a test document shipped in the addon, that you can open to demo mem API:
resource://jid1-rmk6hbj4euqtua-at-jetpack/memtool/data/leak.html
Depends on: 863235
Depends on: 850026
Whiteboard: [MemShrink]
Whiteboard: [MemShrink] → [MemShrink:P1]
Jim Blandy is looking in to baking this idea in.
Flags: needinfo?(dcamp)
Component: Developer Tools → Developer Tools: Memory
I just move the MemShrink:P1 marking from this bug to bug 933006, because that seems to be the main meta-bug tracking memory profiling devtools.

Alexandre, does this bug need to be open any more?
Whiteboard: [MemShrink:P1]
(In reply to Nicholas Nethercote [:njn] (high latency until January 2nd) from comment #4)
> I just move the MemShrink:P1 marking from this bug to bug 933006, because
> that seems to be the main meta-bug tracking memory profiling devtools.
> 
> Alexandre, does this bug need to be open any more?
Flags: needinfo?(poirot.alex)
Yes, I hope bug 933006 is going to end up implementing necessary memory tools!
Status: NEW → RESOLVED
Closed: 9 years ago
Flags: needinfo?(poirot.alex)
Resolution: --- → DUPLICATE
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: