3

My situation is this, I created instance of class at local scope, this instance during construction time assign one of method with binded context as event handler.

Minimal example:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">

    <title>Minimal</title>
    <meta name="description" content="The HTML5 Herald">
    <meta name="author" content="SitePoint">
</head>
<body>
    <a>Hello</a>
    <button>Click</button>
    <script text="javascript">

(function()
{
    class App
    {
        constructor()
        {
            let anchor = document.getElementsByTagName(`a`)[0];
            let anchorHandler = this.sayClicked.bind(this);
            anchor.addEventListener(`click`, anchorHandler, false);
        }

        sayClicked()
        {
            alert(`Clicked`); 
        }
    }

    new App();
})();


    </script>
</body>
</html>

I understand that after IIFE execution only reference to App instance is event handler with binded context. So far so good Chrome memory tab shows me

enter image description here

My issue is, after anchor element removal(remove was realized via console, console was erased), Chrome memory still shows me App instance at the memory. I don't understand it, I believe only reference was eventhandler, according this event handler should be removed also, which means only reference to App instance should be removed too, so I expected garbage collection. Before heap snapshot I forced garbage collection, but App instance is still there

enter image description here

Beside bound _this in native_bind() is window icon and Chrome tells me that it is reachable from window. I tried to examine window but I was not able to reach App instance.

viceriel
  • 835
  • 12
  • 18
  • This might have something to do with the copy of the function `bind` creates ..? – Teemu Jan 24 '20 at 20:39
  • Maybe yes, but I was not able to find anywhere informations about such behaviour. – viceriel Jan 24 '20 at 20:41
  • 1
    https://tc39.es/ecma262/#sec-function.prototype.bind says only, that the function copy is an exotic object. – Teemu Jan 24 '20 at 20:44
  • 1
    I doubt you'll be able to find an exact answer to this question unless it somehow crosses the desk of a V8 developer that happens to have worked specifically on garbage collection, but my estimation would be that it has to do with the way that V8 retains event listeners to make them observable to Developers. As a general rule with few exception you shouldn't be able to see them, but you'll notice even when you delete the element you can still see the event listener in the console. for more info: https://dom.spec.whatwg.org/#observing-event-listeners – zfrisch Jan 24 '20 at 20:45
  • @zfrisch thank you for comment, make sense, but to me seems to me like this feature may cause memory leaks. – viceriel Jan 24 '20 at 21:02
  • @viceriel you're not wrong haha. In the part of the official standard I linked it'll tell you specifically that, which is pretty telling – zfrisch Jan 24 '20 at 21:07

1 Answers1

2

It is difference between remove anchor via console and via your site directly. If you remove element via document then the app won't be in memory anymore. Try this