19

I am building a JavaScript game that creates a Level object using var:

function start() {
   var myGameLevel = new Level(2);
}

This Level object has a lot of functionality, primarily adding elements to the DOM and making them interactive. A simplification:

function Level(i) {
    var _difficulty = i;
            
    this.init = function(){
         jQuery("#container").append(...game elements here...);
         jQuery("#button").on('click', function() {...});
    }
}

My question: How can I know if the Level object created in the start function has been garbage collected or not? I aim to use only var variables so that there are no external references. When the DOM is cleared of all game elements, I EXPECT the Level object to be released from memory, but how can I be sure?

4
  • If you are using Chrome have you tried memory profiling in the debugger? Commented Feb 17, 2015 at 15:19
  • Well, I'm not sure what to look for? Since the whole Level object is anonymous? The Chrome debugger has LOTS of screens, lists, and options. Where would I find my "Level" object?
    – Kokodoko
    Commented Feb 18, 2015 at 12:01
  • @Kokodoko did you get any workaround ?
    – Jay Shah
    Commented Jan 24, 2018 at 22:53
  • I didn't really look into it but you can find memory leaks in the chrome debugger: the RAM memory usage will keep rising and rising if you keep generating objects that don't get garbage collected.
    – Kokodoko
    Commented Jan 25, 2018 at 10:50

3 Answers 3

19

Normally in JavaScript garbage collection is non deterministic. You cant know if or when an object is garbage collected. This applies to objects that are strong referenced.

In ES12 and after, you can use a FinalizationRegistry.

Finalizers lets you handle when an object is garbage collected, using a JavaScript callback. Still the limitation is that, when the callback will get executed is non deterministic. It may take a min or an hour.

// object creation
let abc = new Array(200).fill(true);

const cleanup = new FinalizationRegistry(key => {
  // your code here
});

// tagging variable abc to finalizer
cleanup.register(abc, 'werwer');

// abc = null;
0
9

Weak references are considered a security risk, and thus not available to unprivileged code in browsers.

Those concerns don't apply to privileged code or serverside javascript execution, e.g. via node.js, and thus platform-specific weak reference implementations may be available to them.
E.g. firefox addons can use Components.utils.getWeakReference()

For certain programming patterns WeakMap/WeakSet may be sufficient, but they do not allow the program to observe garbage collection because to do so it would need a key to probe those data structures, but holding onto that key would prevent the objects from being collected in the first place.

An additional concern voiced by JS implementors is that depending on how powerful a hypothetical weak ref APIs would be - e.g. offering finalization notifications - it could expose considerable amounts of GC behavior which in turn could constrain future implementations because changing behavior might break web applications.


Update: There now is a proposal to standardize weak references in JS that mitigates the perceived risks by tying the release of weakly reachable objects to the JS event loop, making the behavior more deterministic.

Update 2: The proposal has been implemented in various browsers as WeakRef

6
  • So you are saying that I actually should never use "var myLevel = Level()" ? This may be good advice, but the question still stands: after I set myLevel to null, how can I be sure that Thing() is not still running code? I find it hard to pin down in the Chrome Inspector.
    – Kokodoko
    Commented Feb 18, 2015 at 15:59
  • No, I'm saying the only way to detect that something has been garbage-collected would be weak references. But weak references are not available to unprivileged code.
    – the8472
    Commented Feb 18, 2015 at 16:34
  • What the hell are you talking about? No where in that link does it mention anything about security risks.
    – B T
    Commented Jun 17, 2015 at 20:44
  • have you not noticed the confidentiality paragraph? confidentiality is part of information security.
    – the8472
    Commented Jun 17, 2015 at 21:10
  • Yes you have reason,
    – user3402040
    Commented Mar 24, 2016 at 11:07
3

I dont think you can control JavaScript garbage collection. Normally an variable or object can be collected if there are no references to it. So you can increase your chances of having an object collected by designing your logic to make the object go out of scope.

1
  • 4
    I don't have to control it, I just want to know if the object has been GC'ed or not. Since the whole thing is anonymous, I can't access it in the console or in the code, but it still might exist.
    – Kokodoko
    Commented Feb 18, 2015 at 12:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.