 So I'm going to talk about memory leaks and all the trouble we had and so on. Before I start, I want to say that this was originally an internal presentation that ran on for a couple of hours and the show went tell, you know, we all were trying out things and so on. I've been trying to size it down for this, but yesterday I had a charge of my functions so I was just doing it now. So there's going to be a couple of raw things in this, you know, to bear with that. The second thing is I'm notorious for talking really fast. So if you see that I'm talking fast, you'll have to let me know. I'll slow down. All right. So I'm Vishnu Mayangar and I work, I direct, I talk to Tuki. And that's my Twitter and GitHub handle. Vishnu, can we talk in the mic? Yeah. Okay. Is this better? Do another mic if you want. No, I think it's easier. So I'm going to talk about some of the trouble we had in memory leaks, right? So let's start with how do you know that you have a memory leak? So relevant to this is the application that we're building, which is top dot two. It's a chat solution and among the various parts of a chat solution is a chat client. So because we wanted to build a chat client and we wanted it available on different platforms, mobile, on machines, you know, desktop and so on and on the web. And we wanted to build different clients for these. We thought we'd cheat and we'll just build one client for both web and desktop. So it's essentially a web client. And on the desktop, we bundle this with a browser and we make a few, we have an additional component in there, which gives you the desktop like feature. So it's a web client, but it's very different because, you know, people expect it to act like a desktop client, which means that you have expectations of being able to run it for a very long time. You know, you've run it for days at a time. And it's also the kind of, I mean, because chat client is stuff that's constantly going on. You know, first of all, your engagement with it is largely large. You're on it quite a bit of the day where you're chatting with people. Messages keep coming in. People go online and offline. Your roster has to change. So all this stuff that's going on. So, you know, you're working on this for quite a bit and every once in a while, they release something new when you are testing it. The QA guys pull it and they tell us, okay, move this box in three pixels to the right. That's our thing. And it all seems fine until we release it. Then you go ask people, you know, how are things? How do you like the client? And people are like, yeah, it's okay. And, you know, you want to know what you did wrong. So you dig a little more and then they say, it's really slow. And that doesn't make sense. You know, modern browsers are pretty fast. JavaScript has changed so much. Are they using an old browser? You're not sure what it is. So you go to their machine, you start to client up and it's fine. And then they say, yeah, it's fine. Now, you know, wait a couple of hours, it becomes really slow. That's usually a good sign that you have memory leak, right? In fact, they'll tell you things like, I'm doing something else and I get a ping because somebody messaged me and I switch to the client and it takes so long for the client to come up. It takes so long for me to click and do anything. So what that means is that you're using a lot of memory and ultimately the OS has started paging your stuff out of memory. And now when you switch back, it's pulling stuff back from hard disk. And hard disk is just way slower than memory. That's the problem. So that's when you know you have memory leak. And the kind of applications that have memory leaks are essentially what I mentioned. I mean, most web applications are short lived. You know, you're on the page for maybe 10 minutes, so half an hour. But ones that are there for a long time is where you start to have a problem because on a client that's short lived, you don't have to worry. I mean, even if you leak memory, you're not going to notice. But this client is something which has a huge number of elements. It's a fairly large application. So that's one thing that's going to leak to memory leaks. The second part is, I mean, you've got dynamic elements that are constantly being created and destroyed. I chat with somebody. I create a chat tab. Something comes online. I create an element, represent that person, and so on. So there's elements being created and destroyed all the time. And it's got to stay away. You know, stay online for like three, four days a week, whatever. How long? You don't want to keep it. So you can't afford to leak memory at this point. And the other thing that will contribute to this is if you have a large enough team, or the code base is complex enough, then you can't work with a simplified model. You start using various abstractions that are commonly powerful for this kind of thing. You start using a component-based model. You have widgets that develop by different people. And as the scale becomes large, it's harder to reason about what's going on. And all these things contribute to, you know, first of all, there being a memory leak, and then it being hard to even discover that the memory leak exists. So let's talk about how you can get a memory leak in JavaScript. So back when we all learned C, there was this point where you learn about how you allocate memory every time you want to create an object. It's based on the game. And when you're done, you delete it. And I mean, memory leaks meant that you forgot to delete something that you allocated. But, you know, JavaScript is memory managed. You shouldn't have to do all that. So what happened? So the question is how is memory reclaimed on JavaScript? So really it comes down to this whole thing about scope. When you say new object, whatever, JavaScript's allocating memory on the game. And it's waiting till that reference is out of scope until there's no references pointing to your object. And then it's going to reclaim it. And that's really all it is. So, I mean, it should be fairly simple to deal with. I mean, think a little complex with closures because JavaScript has closures, right? If I retain a function, the function has access to everything that was in scope at that point in time. So technically, it's possible that you'll be holding on to stuff that you don't realize you're holding on to. And you've got to figure out what gets ahead and what doesn't. All right. At this point, I'm going to switch to the demo. And... Oh, there we go. Right. So, let's actually take a look at this. So I've got this. I mean, this is the HTML file. And in most of the cases, I'm actually going to switch to the file and then switch back to Chrome. Now, I'm going to use Chrome for this because the Chrome's Web Inspector is really good, especially if you're trying to figure out what's going on in the heap and so on. So, we'll be using that as an example. Obviously, different browsers are going to have different tools and they're all not going to work the same way. This is a really, really... I mean, there's nothing in this file really, right? I just created this object first with the little manner and then I'm creating the object using the constructor mechanism. So, you've got the stuff and another. Now, the first question is, you know, how long is this object going to stay on the heap? Both of these. Forever. Forever. So, if we switch to Chrome, I'm just going to take a heap snapshot. We're looking for this thing that was called Movie. This is the slowest part of the session. Searching for the stuff. Thank you so much. That's it. There we go. Right. So, we can see this is the one we created. Now, there are two objects and one of them actually represents the function itself which is a little confusing. So, yeah, you can see this is here and I want to take it out of the mistake. So, we know it's called another, right? Now, I say delete another. Does this work? Let's take another snapshot and we can actually do a comparison. Then let me search now, does it? So, you can see it's not here, right? It didn't seem to clear it. Let me switch away from the comparison mode. There's still two objects. It didn't clear it even though I deleted it. So, this was the first gotcha. It confused us for a long time. The problem is the console. If you type something on the console, it's going to stay forever. So, for the rest of the presentation, I can't use the console. So, I'm just going to refresh this. I actually have to kill the tab just to make this work. So, let's do this again. I believe we should get deleted now. There we go. So, we've lost one object. It's been deleted. So, this is... I mean, we just see that stuff can be removed from scope. So, now, a lot of people just trying to figure out what is held in scope and what's not. Now, there's a second part of this where I've got this make object that's going to create a movie but it's not going to let out a scope. In this case, clearly, we expected not to live. So, I mean... So, we just have to call the function. We can see that. And I should just take another snapshot. I mean, the number of movies should be the same. There we go. And now, it shows one. But, yeah, I already deleted the first one. So, there we go. So, this is... So, we see that stuff is removed from scope if you delete it from the global scope. Otherwise, as long as it's stuck in a scope, one of the scope end should vanish. So, now, let's take a look at what happens at the closure. This is only... we just change it most into something of a... a force which is not reclaimed as memory or... You're talking about how GC works, right? Yeah, I don't want to really get into the complications of GC because there's so many different implementations. And, I mean, I feel that out of scope over here. But, let's just talk about it at a very, very rough thing for the sake of the discussion. I mean, you're right. Most of them probably use these generational GCs and so on. But, at a basic level, we know that the way GC works is that when all the references come to that object is zero, it's going to be a pre-claimed. And, old GCs used to have a problem. Old GCs used to have this problem where they would count the number of references to an object. Now, you could have two objects referring to each other, and that's going to happen all the time. You'll have... I mean, if you want to build a complex in a core base, you want to end up with this cycle. At one point, they could not clear it, but no modern browser has this problem. So, you will never have trouble with cycles anymore. There's a second kind of cycle that people used to have trouble with, but I'll come to that when we come up with DOM. So, a quick question. Let's say I have a DOM element. I detach it from my DOM, put it in a document fragment. And the document fragment goes, let's say, in a reference called A. And the scope finishes, and the document fragment is lost. So, will all this DOM stuff also get cleared, or is this just true for JavaScript variables? Can you hold on to that and make it DOM? Oh, sure. The reason being that it becomes a more complicated DOM. So, I wanted to start with just pure JavaScript for a bit. So, let's take a look at this one. This is Closure Scopes. So, I've got this button called Make Closure. Now, as I said, I'm not using the console, so I have to keep showing you files and then pressing buttons on the screen. It's going to feel very clunky, but that's the best we can do at the moment. See, I've got this function with this button, which is going to be called Make Closure. And so, this is that movie object again. Here's Make Closure, where I say Make Function. And I'm just... Yeah, I'm just... I'm just executing the function and putting the return value in this div called Closure, which is up here, a spam called Closure. Make Function is going to create a movie and return the function with the movie trapped in the closure, but it just returns the string, which is the title of the movie, when you execute it. So, it doesn't actually return the movie object. Now, clearly in this case, we know that it should be trapped in the scope. So, let's actually look at that and then we can look at a relative piece. Oh, I broke it somewhere. If everybody sees it, let me know. Where's that? Function. Oh. No. Thank you. That's what you meant, right? You think I did this? It's the same, but yeah, okay. I don't know what you're doing there. All right. So, let's refresh the page. Take a snapshot before. And let's press the button and take a snapshot again. Now, one thing I've deliberately done is in that... Where is that thing? Make Closure. I've stored Function in a global variable. I mean, that's deliberate. I'm talking about what you're going to do in real life, but it's just to make a point in this case. And we should find the movie is there. The same one I did. Yeah. So, now the question is, if this is true and closure strap objects, you know, then are we screwed? Because technically inside a closure, you can access everything outside, right? So, if you ever return a Function, does that mean that every single thing is an experiment where we're going to create four movies and we decide that why that is not a talented movie. So, we only put the remaining in this talent movies array. And now we're turning a Function, which is just going to randomly, you know, pick movies from this. And then we've got this Make Suggester, which I believe is the second button being called, which is now going to create this movie Suggester, which is just random talent movies. And then I print this 10 times. That's really all I'm doing. So, we do the same thing. Come back here. And I've already taken a snapshot before, so I do this. And there we go. So, Twilight's not in there. Ideally, it would be great if Twilight is not caught in the scope. And, okay, we've got five. And we should see. So, clearly, the browser is smarter these days. If you're using a closure, it's only going to trap those things that are referenced in there. Now, they're doing some sort of parsing to figure this out. Clearly, there are places that are going to break. First of all, JavaScript has eval. If you eval, then all the ways are off. So, if you're returning a function that's going to eval, they're no longer going to guarantee anything. There are a couple of other places where they don't guarantee anything. I think if you use width, they do the same thing. They clean it as an eval scope. So, in both those cases, you don't know what you're doing. But otherwise, if you're using closure, you should be okay. If you know what you're referencing, that's the only thing you're holding. So, if it's that intelligent, why is it not storing only title? Why is it storing only title? It's not that intelligent. And also, just to try to understand, yes, and fun, you have made it a global variable to make sure it's not... Yes, I wanted to live for this page. Yes. This first section in the page is just a demonstration of scopes. And the second part is where people usually leak memory. All right. I mean, they had an eval this thing, but I dropped that example, so I'm not going to get into that. Now, I'm going to refresh the page again because the lack of memory, I'm going to kill the tab and do this again because otherwise, each subsequent page is going to have all the stuff trapped open in the previous pages. Now, we're getting to DOM. So, again, this is basic stuff about DOM first. We know that... So, let's talk about how DOM actually works. Now, we know that all the browser objects are all in C++, right? This whole thing is not in JavaScript. Whereas, but within JavaScript, you have complete access to the DOM. You can travel to DOM. The DOM object themselves seem to reference each other because, you know, from an object, you can access its parent, you can access siblings and children. So, if you're in the DOM, which is the attached DOM, you can travel around anywhere. And on top of that, you also get access to that in JavaScript. In JavaScript, if I get access to an element, I can do parent element and I get access to another DOM element. I can do siblings and children or I can do next sibling, previous sibling, and so on. So, you know, let's figure out how this really works because it's relevant to this discussion. So, even though all those objects are in C++, what's happening is that the proxy objects that are being created in the JavaScript world, the proxy object refers to the C++ object and that's how you get access to it. But these proxy objects don't exist for every single element of the DOM. They're created on demand. So, when you try and refer to something, it creates the object until then it's lazy. So, you're not going to have too many JavaScript objects that represent DOM objects all the time. Whenever you use them, they exist and they're tied to the DOM object. Yeah, thanks. Do you want me to repeat the image? No, no. So, yeah, I was saying that you have proxy objects in JavaScript that represent each element of the DOM that you end up accessing at some point to the other. But technically, it can create one proxy for each element that exists in the DOM. Now, in the DOM itself, these objects refer to each other. So, it will clean up cycles. If some part of the DOM vanishes, it will collect it. And it's got its own garbage collection world in the C++ thing that we have no access to. Similarly, in the JavaScript side, we know these codes work. Now, it's possible for JavaScript and DOM objects to refer to each other and we know it. So, here are simple examples. We've got the first button which is calling hold some DOM where we're just getting hold and we're then removing it from the DOM. But restoring it in a glow. So, now we're holding on to an element there. Now, I don't think I actually mean... Oh, no, I'm using the movie down further. Right. Then in here, we're actually not going to see much in this particular case, I think. I forgot. So, I hold some DOM and I see what it had and it had this string. Just to run you through what happened because I'm not sure if all of you caught that. So, I hold some DOM was getting hold of this div called snafu, I believe, up here, which has this string, tura, tura, tura. I got hold of the div up here. I stored it in a JavaScript variable. I then removed the div from the DOM. So, the C++ side is no longer referring to that object. But, I was able to clearly... When I did see what it had, which is a second button I pressed, I was able to see the result. So, clearly the C++ object lives I mean, I can't show that to you in the inspector because the inspector does not show you the C++ object. But, we know that it lives. So, from the JavaScript end, I can hold on to DOM. And then there's the reverse. So, out here, I've got this other button which is called attach handler, where I'm getting hold of result and I'm attaching a click handler where I'm just going to print the movie title. Now, sorry, go on. Is it cloning the object or is it just a reference? How do you know which one it is? Well, it just creates a new proxy object. Technically, you can't know what's going on the C++ world because every browser is free to implement its own. But, the most likely thing is that they're just giving you a proxy for the same object again. There's no need for them to clone it because I mean, when you modify the object for multiple references, the object for all references. So, if you have multiple copies in JavaScript of the same object, you change the text or whatever. All of them will see that. So, there's no need to clone it. I mean, they're just giving you a second proxy. Right. So, does it mean that you document that gets element by ID same, now they give you the same reference object or you think that's a new JavaScript reference. I mean, new JavaScript proxy but refers to the same C++ object. So, you're asking me whether it shares the reference in the JavaScript world. Is that it? Yeah. So, is it two JavaScript references related to the same JavaScript proxy? I'll repeat the question. Go on. Many of you should just keep it here. Is it two JavaScript references referring to the same JavaScript reference object? It's not on. So, is it two JavaScript variables references referring to the same JavaScript proxy object or are they using proxy objects with their own references which refers to the same C++ What do you expect of the answer? So, let me put it a different way. If I get hold of the reference twice and I set a property on one, do you expect to see the property in the other? Both will work because ultimately they refer to the same C++ object. So, if I add a JavaScript property, if I do, you know, document and then I say .x equal to the JavaScript property, it has nothing to do with the C++ word, right? Okay, I got it. So, you're saying, if I add a property to the JavaScript property, the other one wouldn't remember it? No, the other one also sees it. That's why it's a shared reference. The proxy object or it will have multiple proxies to the same C++ It is, I'm in the same question and there's single proxy. So, my expectation is completely compatible with being the same proxy. I know that in JavaScript if I do something to one of those objects, every reference should get modified. So, that's the reason they give you the same proxy. Torotoro there is a proxy object, right? Or is it a reference object? Well, it's a reference to a proxy. Yeah, reference to a proxy. So, wouldn't the reference to a proxy get deleted or something after the function is finished? It's global. I've not done what. It's literally making everything global. Right. Shall I move on? Next example. So, yeah. I'm getting hold of results and oh, I think I mentioned this but yeah. It's just a click handler on which I'm axing the dom and doing this. Right. And now, I should look for movies. That's okay. I've already taken the gif snapshot and there's nothing to see. I don't know where the gif is. It was this one, right? And let's just take a comparison. I think with a search it's now easier not to take comparison. So, the movie isn't there. So, we can see that not only can we do this but the DOM work can hold on to the JavaScript side. Now, you could ask is it just a proxy object holding on to the JavaScript? How do you know if the DOM side holds the object holding on to the proxy side? And the answer is that for efficiency reasons, it makes sense for the DOM side to do it. If the JavaScript side is attaching click handlers to every proxy then they'll have to always call in the JavaScript word to do something. So, for efficiency reasons the DOM side actually knows that there's an image handler but that's just a magic one so I can't show you anything. So, yeah, that's the purpose of this was just to show you that we know that DOM holds on to JavaScript and JavaScript holds on to DOM in these two worlds of C++ and JavaScript. Now, again, this is again later cycles that somebody talked about. I think even as far back as 2007, you used to have process where if you have a DOM that's holding on to, I mean had a click handler or whatever and inside the handler you're holding or reference to the DOM then you have a cycle across two worlds and you'll never get clear up. You're not going to see that anymore. Most modern browsers don't do that. So, again, you're safe from those problems. Most of the issues where you can blame the memory leak on somebody else are gone. Now, I mean right now memory leaks only mean that somehow your objects are being held on to by the global scope. That's all that memory leaks are. So, Define when we can start blaming and when we can I actually don't know the answer to that, sorry. Okay. I don't know when they fixed that. I know I6 had the problem and they fixed it. So it's very old problem of the cycle. So, yeah, I love my thing of the art. Yeah, I was talking about cycles and I said cycles are not an issue anymore. So, every what I say, every problem that you're going to have is going to be because somewhere in window you have access, I mean you have a bunch of objects, your functions of your other objects that you define that are then holding on to other objects and somewhere they're holding on to DOM and those things which you no longer are using are the memory leaks. That's really all it is. So, I mean, at this point clearly it becomes an error on the JavaScript programmer side but that's it. Memory leaked, I mean memory managed languages have always had memory leaks. It's not just C++ world. I mean the Java world and the dotnet world have had a share of memory leaks. So, even there the answer is the same. You're holding on to stuff. If your application is complex enough you're not going to realize you're doing this and you'll probably have some map somewhere, some array somewhere that you're not paying attention to that's going to hold on to something. That's really all it is. So, I'm going to sort of cover through the presentation certain sort of common patterns that people use where they run into this trouble and they're not aware that they're holding on to a reference. That's what the rest of the talk is going to be. Before that I was thinking we would actually take a look at the memory leak and see what it looks like. I'm going to look at the file first. Right. So, I've got a button called create some DOM which says create a div which is a mistake to create some DOM. It's no longer one div clearly. So, what I'm doing is when you take create some DOM, I make an element and I then push it onto this array, global array and then I'm appending it to this container div. So, every time you press the button I'm just making this thing and putting it there. And in the beginning I just created one div but the memory grows so slow that I did this and hopefully you can see some results. Then I've got this other function called start creating. What this is going to do is as long as this flag is true and it's a flag so I call it flag it's going to set a time to create some DOM and then it'll just again start creating. I'm doing this as a set time out and it should be apparent why. If I don't do that it's going to be an infinite loop. I'll never be able to stop it. This actually gives me access to be able to stop it. You should close the which tag, sorry. Oh, thanks. Maybe that just made the DOM more complex. I don't know. I really, really forgive forgiving. Stop is just going to turn the flag off. So this process of creating this thing should stop and remove is going to go to the container and just clear the DOM. Now we know by now that this is going to leak DOM because I've been storing all the elements in this array. So we know that from the JavaScript side we're going to leak DOM. Let's take a look at it in the Web Inspector. This is just going to create that here. So I start creating and now I think we can go to the task manager here and take a look at the memory growing. So, yeah, it's I mean it's visible now at least, right? But 1MB a second or something like that. So, I mean you can see it's clearly growing as some CPU activity but it's not 100 so I get a chance to stop this thing. Now what I'm going to do is let's take a look at the Web Inspector and see what we can see. So it's going to get close to about 90MB in like you know 10 to 15 seconds less than that actually. So I'm going to stop it now and I'll clear it. Now let's go here take a snapshot and let's see what it tells us. Okay. So according to this the shallow size is like 1MB of this array and I mean you can just tell looking at those numbers that it's not going to add up, right? It's nowhere near the amount of memory that we are actually using. So I mean by now I guess some of you already figured out what the deal is but the point is that very hard from this to figure out where the memory is being used. So the count is clear is the count of the JavaScript object but what's not represented here is the C++ the DOM objects are not going to show up here. So if you are leaking memory it's from this at this point in time you still can't tell where you are leaking memory what the biggest thing to shoot is. Now this gives you the constructor of the object which created the thing in the JavaScript side the objects count is again clear shallow size refers to the actual proxy object the retail size is a bit confusing it's trying to tell you what other JavaScript objects it thinks you are holding it's wrong half the time so you really can't depend on it yet and the retail size the way it works that thing has got to add up to more than the total amount of JavaScript memory because multiple objects will there's another view I mean out here you can go you can see the summary, you can see the comparison and the containment view is where you start following back and figure out what holding onto my object. Now the point of this is that most other places where you deal with memory leaks the common way of looking at it is to figure out what's taking the most memory after you run the plugin for a while and then just find that and shoot it you can't do that because you'll take a lot of memory in completely innocuous places the actual leak is somewhere in dong and this you might have a large count of something but it's not going to be clear and if you're using some kind of large JavaScript framework which is doing all these clever things with closure and so on, half your functions would have constructors which have names so you won't be able to figure out what those things are you'll just see a bunch of function, function, function and there'll be a large count of them and they're different places, they're not even referring to the same object anymore so it becomes quite hard using this to figure out where the memory is leaking and how quickly you can solve the problem I mean the point of this was again to make sure that you're all in despair about this world yet and we will eventually hopefully get the tools we need from what I know there are some experimental bits of Chrome that have some kind of I mean sorry, 15 5 no way so they're giving you some kind of memory counter or something of that sort but yeah alright let's go back I mean I was getting to the meat of the discussion now which is what leads memory how it leads memory let's move on after its leak memory does it go away once you turn on the next page sorry so I mean again this is very specific to a browser and all that so from what I remember as long as it was in the same domain they keep the memory and even if you have multiple tabs in the same domain they share memory but if you navigate away from the domain then they can clean it up at least close the tab but I mean I can't tell you but from what I know as long as you navigate away to a different domain they know that they don't have to keep the obvies anymore for some reason they use the same process for everything in the same domain I think it's because they're allowing you to communicate across pages and stuff like that right so yeah this is a trivial example but there's a big point to this so creating a thousand divs and appending it there and that's what this button up here is going to do I mean I'll call the creator and I'll clear I will just empty them and the question is you know how much are we leaking I mean the opposite thing is here again LM is global so let's figure out how much leaks I'll create a thousand divs I mean the comment actually gave it away I think so we actually don't leak much over here the point is that we know that within the C++ world you can navigate from objects to the siblings so the expectation is that if you're holding on to one object then why aren't you holding on to all the other and again this is just from being really smart what is the thing called that we're looking for oh it's a div right still doesn't have any so yeah I mean we don't have any so it's being smart it says that once you hold on to one object and you retract it off then you are not expected to be able to navigate along the siblings anymore then clear the siblings they won't clear children but that's the deal let's move on prototypes this is very specific to one kind of problem that occurs when you're using frameworks so the framework I'm using in this example is dojo which give you this classical structure and the classical structure is very easy to reason about as opposed to product structure so a lot of frameworks do that so this is one trap that people frequently fall into about how they leak memory when they do that so let me show you that so the way it works in dojo you can declare a class declare a breadth producer and I've got a field called button and then I've got these three functions right actually this is the solution to the problem we know that for now and pretend I didn't show it to you there we go so I've got this button producer and when you say create it actually creates a button and what it's doing is storing the buttons in an array and then when you say change color it will change the color on all the buttons let me actually show what it looks like so I produce buttons I make them blue and they turn blue and that's it now the point is when you create let's see what happens so I've created buttons and I've said that the button producer says that whenever you do this I'll iterate over the buttons and I'll change the color now what I've done over here let's go to the top I've called produce and produce is going to say it's going to create a button producer and for each one it's going to create a button that's fine and then change color is being called to the button producer itself and I say blue now the question is if you look at empty we just take going to the button area and setting the html to blank so why is it that the buttons are being used I mean because of the fact that the prototype the thing so a lot of things will give you this way to create fields called buttons and what they're going to do is mix it in but they expect you to realize that when you do this buttons are actually on the prototype object so if I create two button producers they share the buttons which I say fields and so even though I'm deleting all the buttons they share across all of them and so on so I'm not going to bother running through this example I expect mother clear it you'll see a bunch of buttons in there and the solution is just to make sure the button is declared on the I mean the cut-stuff top so the thing is in JavaScript if you set a property on an object it's always setting it on the most adjacent object it doesn't go on the product chain if you're trying to get it then it will follow the product chain as far as possible until it finds that object so over here the mixing thing was causing an issue so I mean you don't have to beware anytime you use any such framework even in JavaScript in this raw form sometimes they do these things that make code look very convenient not necessarily what you expect though alright so there's closure so let's do what we do so we produce an unsafe toggler and toggler is empty so unsafe toggler says that it returns the toggler to you function the toggler is basically going to take a button and swap the background color and the color itself and we're using dojo here but it's the same as having an event listener on click it's going to call the toggler and we return the toggler function now what we're doing is when we create these buttons we're storing only the toggler functions and not the I mean but we've covered the sort of closure thing and we know that this probably won't hold on to the button right so on emptying it it's not going to clear the area clear the area so I mean since we've seen the example I'm not going to show you how to fix this because in case you want this kind of pattern and there we go sometimes you can't report to the object you have to break that closure in this case what we're doing is using id so you know that and make sure it's not referring to the scope break it using a string or something some immutable object which is small whereas the button object might be large and could leave so I've covered jquery on p and the dojo widget p one question on closure if these variables created so that the past tree is first created if past tree is first created I'll just repeat the question so there are n number of variables that you would have declared and you would have let's say referred that variable alone inside your let's say so this means that the javascript function is first created into a past tree and the compiler finds out which are the closure variables which are potentially referred inside the variable you're getting an implementation of the engine and I really can't talk about that I mean I don't know enough about it I could make a guess but probably not a good idea so it's better if we just tell you what I know happens I mean this might be specific to different browsers and different engines but this behavior is the same everywhere but you know for a fact that if you do eval again they're trying to be smart about eval what they're saying is that they cannot guarantee anything with eval because eval they have no idea what you're really doing now they'll keep closing that boundary every once in a while they'll take a look and say some pattern people use eval and I can guess what he's trying to do over here but you know unless they can be 100% same they can't afford to reclaim those objects so every time they notice something new they'll sort of say okay this is a pattern of eval that you can afford to reclaim but since eval essentially takes a string they have no idea what the contents of the string are you know if they freeze a string they may be able to figure it out so they've got ways to intern strings now and so on but again it becomes really complicated it's possible they could create an immutable function based on the string so that the same function can be repeated again yeah that provided the string itself is not a parameter of some pattern I mean the minute the string starts coming from some text area you have no idea what's going to happen anymore so I mean let's take a look at jQuery on because jQuery on is something that people use a lot so there are multiple ways to use jQuery and now there's a more recommended way but let's look at the old way and people know one problem with it which is you know the memory leak issue it's interesting because this one is not so apparent so I've got this randomizer and it takes the account as a variable and stores it as a field and then make text is actually going to get hold of this span with that count and it's going to store a random number in there so that's simple now the button over here is going to say create one and I have a crave min so we can look at both so create one says every time you say create one it's going to increment this count it's going to make elements get a randomizer and then it says on find this button on click make text and it passes that function now what I've done over here is make elements is creating a div which is a hold of inside which I'm setting a button with this id and a span with the same id and I'm pinning it to container so just to show you this if you go here I have this and they expect me to be setting this to such a random number create many is just creating a thousand of those so they're all just independent troubles now clear is going to actually remove which is just going to set this in HTML now at this point I haven't trapped anything in a closure I haven't really done anything all I've done is you know set this on click touch this but let's see if this is leaking and you know that it's going to have to leak or I wouldn't bother showing you this let me just repeat this not sure what I missed oh is it so we can see we've got a thousand button element thousand div element but we have span we have six span element what's going on because for every button we created a span and we put them in a div and for every touch pair we have a randomizer so why is it that we have thousand of each and just one span I mean a six span you know what I guess so the answer is that I never referred to the span anywhere the proxy was never created so again remember that the memory provider can't fool you there actually are thousand spans there you just can't see them in this because I never referred to them I've referred to everything else in this creation process which is why the proxy objects exist there are buttons and randomizers so why six then I have no idea must be this markup there are other parts I don't even see any span there so I don't know it's possible so they're not saying that they're going to not create the proxy objects maybe they start creating a few and then they give up at some point sorry oh yeah that's a good point I probably should six buttons I wasn't thinking about that so yeah so the reason that the memory is being linked is because of if you think about it if jQuery is doing this it's not magic you don't have to hold on to these objects so if you use this pattern with jQuery you are bound to leak memory to clear on the DOM and I'm going to do the same thing with the safe manner and clear it up so let's do that let's actually remove the... oh I don't have any snapshots anyway so create these the same things they work so we take clear let's take a snapshot because the difference should not see these things so yeah I mean I've got like four buttons so clearly it works so I mean what's different so there are two ways to solve this problem there's one way which is very recommended right now for other reasons which is don't create a thousand handlers so now they recommend that you know you attach the handler to the container object and then you know you smartly figure it out in this case it would be a bit annoying because you have to get hold of the button figure out the ID, figure out the number and then find the corresponding span but you could do it that way or maybe you could travel the DOM and find it and what I've done here is with the current pattern how do you fix it so now I've got handlers which is a hash and every time I create this I'm storing the function handler that I've passed to the bottom right so earlier I was just passing the function inline now I've stored the function inside a variable and then I'm passing it in and that's stored in a hash and now when I remove I actually say jQuery off of all of those handlers on those objects which then takes out those corresponding handlers and then it's safe to clear the thing then when I call remove it to mine so this is the correct way to do it if you have a complex enough application there are points where you might use the smart jQuery handlers but sometimes even the containing div is going to vanish because you really don't want to attach everything to the body that's actually going to slow down the processing so you will attach them to some smart container you know if you have a widget you're going to attach it to the container but if the widget itself vanishes you'll have to take care of destroying the handler so you're going to have to store the handler so in a way you know you would think that as long as you're not holding global references everything will be fine here's a place where you actually have to create something like a global reference at least global to that scope and clear it up so if you start doing this stuff with event handlers you might actually have to create scope and in your mind it will look like you're making the problem worse before you fix it so again I mean the same way the jQuery recommend is fairly good for a small enough ever application where you know that the containing element is never going to vanish it's only in cases where no matter what container you've chosen it might vanish and you don't want it to live forever that you're going to have to look at this process and figure it out and use jQuery off probably one of the least used jQuery problems so how am I doing in time? 10 minutes fast I'll do one more and I'll stop at this point I'm just talking about the widgets of dojo and this is interesting for a different reason again it's something you know if you're building an application you might end up using dojo so for large problems let's go up so let's go up here and I create widgets and let's take a look at the memory meanwhile I'll show you what's going on I've declared my button it's a widget so it's got a template and it's got all these things and when you click the button it does some stuff it's a dojo object which internally is going to create an HTML button and I'm just creating a thousand of them they're not stored anywhere this isn't global nothing if we take a look at the heap we're going to see a thousand of these buttons so the reason this is happening is that dojo when you create a widget and with this template and so on it's going to create DOM and hold on to it and the expectation that they have is that you actually call destroy when you're done with it so with the widget lifecycle this might seem painful but the reason they're doing this is because they're trying to give you another advantage when you're trying to build something with widgets and it's big it's not going to be easy for you to hold on to all these things you're factored your code base in a particular way you've come up with these various layers but you're going to have to find ways to transfer control to one place to another typically they give you access to magic ways of getting access to things for example dojo digit which is the widget library which is another widget from somewhere so it's like it's a global hashtag but it's maintaining so instead of having you do the plumbing they're doing the plumbing but correspondingly you have to destroy this is similar to what happened to the jQuery click handle I had to show the click handle and that's the reason why I had to destroy so if you find that something is letting you access stuff without storing it in a variable then you have to question that somebody is doing it if it's not you so the minute you find that you have access to things across scope and you're not storing it in a global variable somebody must be doing it and if they do they'll have a life cycle that let you destroy it so that was the point of this so I think I'm done there so I'll just take questions at this point you want to take the mark line? yeah I think some people want to take a coffee break or something thanks Vishal