Open Bug 960675 Opened 11 years ago Updated 2 years ago

Should have console methods to find leaked objects' paths

Categories

(DevTools :: Memory, defect, P3)

x86
macOS
defect

Tracking

(Not tracked)

People

(Reporter: fitzgen, Unassigned)

References

Details

We can use the BFS path finding algorithm described above to add arbitrary JS objects **that the user expects to be reclaimed** to a WeakSet (polyfill-able from JS on top of WeakMap and Cu.nondeterministicWeakMapKeys or whatever its called). Later, when the user calls console.retainedObjects() we can use the path finding algorithm on each of the objects still accessible in our WeakSet and log the retaining path to the console. Now the user knows why the given objects are being retained and not reclaimed.

The  benefit of implementing this early, before the whole memory tool is ready, is  that we can get early users to shake out bugs in our path finding algorithm and land tests so no one else breaks our stuff, etc.
Proposed API (need help with method names):

Called to add some objects to our weak set:

  console.expectReclaimed(...objects)

Called when it is expected that the objects added to the weak set should no longer be alive, and dumps their retaining paths to the console:

  console.retainedObjects()
(In reply to Nick Fitzgerald [:fitzgen] from comment #0)
> We can use the BFS path finding algorithm described above
above?

> to add arbitrary
> JS objects **that the user expects to be reclaimed** to a WeakSet
> (polyfill-able from JS on top of WeakMap and Cu.nondeterministicWeakMapKeys
> or whatever its called)
Feel free to steal bug 792439 ;-)

> Later, when the user calls
> console.retainedObjects() we can use the path finding algorithm on each of
> the objects still accessible in our WeakSet and log the retaining path to
> the console. Now the user knows why the given objects are being retained and
> not reclaimed.
I love it! For to be sure, all of that is purely interacting with the console and never leaks anything to the runtime?


(In reply to Nick Fitzgerald [:fitzgen] from comment #1)
> Proposed API (need help with method names):
I would add a string key to create different weaksets for different purposes (async concurrent programming will probably require that sooner or later)

> Called to add some objects to our weak set:
> 
>   console.expectReclaimed(...objects)
Maybe console.observeLiveness(key, ...objects)?
 
> Called when it is expected that the objects added to the weak set should no
> longer be alive, and dumps their retaining paths to the console:
> 
>   console.retainedObjects()
... I feel this is too global.
idea:

  var o = {}, o2 = {};
  var logClickLiveness = console.observeLiveness(o); // o added to some WeakSet
  var logKeyLiveness = console.observeLiveness(o2); // o2 added to another WeakSet
  logClickLiveness(); // logs on the console the paths to 'o'
  document.addEventListener('click', e => {
    o = undefined;
    logClickLiveness(); // o isn't retained anymore, so a message says that all objects have disappeared
    logKeyLiveness(); // o2 is still retained, its path is logged on console.
  })

Not sure I made the names that much better :-/
Depends on: 961323
(In reply to David Bruant from comment #2)
> (In reply to Nick Fitzgerald [:fitzgen] from comment #0)
> > We can use the BFS path finding algorithm described above
> above?

err bug 961323


> 
> > to add arbitrary
> > JS objects **that the user expects to be reclaimed** to a WeakSet
> > (polyfill-able from JS on top of WeakMap and Cu.nondeterministicWeakMapKeys
> > or whatever its called)
> Feel free to steal bug 792439 ;-)

Different because the es6 weak sets aren't iterable, and what we need here is.

> 
> > Later, when the user calls
> > console.retainedObjects() we can use the path finding algorithm on each of
> > the objects still accessible in our WeakSet and log the retaining path to
> > the console. Now the user knows why the given objects are being retained and
> > not reclaimed.
> I love it! For to be sure, all of that is purely interacting with the
> console and never leaks anything to the runtime?

This shouldn't change program behavior. If there is anything different between when it is there or isn't other than perhaps a couple ms of processing time, that is bad.

> 
> 
> (In reply to Nick Fitzgerald [:fitzgen] from comment #1)
> > Proposed API (need help with method names):
> I would add a string key to create different weaksets for different purposes
> (async concurrent programming will probably require that sooner or later)


Interesting idea. Will have to mull this over.
Has recent memory work helped us here, or are we waiting on platform APIs to be added?

Such a feature sounds very helpful for intermittent test issues I frequently pull my hair out over...
Flags: needinfo?(nfitzgerald)
(In reply to J. Ryan Stinnett [:jryans] from comment #4)
> Has recent memory work helped us here, or are we waiting on platform APIs to
> be added?
> 
> Such a feature sounds very helpful for intermittent test issues I frequently
> pull my hair out over...

The priority has been on other things, so there hasn't been any progress here or in the dependent bugs. Maybe Q2? Not sure yet.
Flags: needinfo?(nfitzgerald)
(In reply to J. Ryan Stinnett [:jryans] from comment #4)
> Such a feature sounds very helpful for intermittent test issues I frequently
> pull my hair out over...

You can sort of do this using existing JS heap logging, though the experience is not very pleasant, plus for rare intermittents I'm not sure how you'd use it.
Has STR: --- → irrelevant
Priority: -- → P3
Product: Firefox → DevTools
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.