Only The Best Developers Understand How This Works

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you want to be a top tier JavaScript developer then you need to have a Mastery over how JavaScript handles memory so in this video I'm going to be covering everything from the simple concepts of how garbage collection works all the way up to the incredibly complex concepts of how to use your Advanced debugging tools to find things like memory leaks inside of your application welcome back to web def simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream project sooner now the very first thing I want to mention anytime you're dealing with memory management is I highly recommend you do this inside of an incognito tab in your browser for example here I have this entire web app open in an incognito tab it's a blank web app because there's not much going on but I want you to open it in an incognito tab because otherwise you're going to get memory for all your extensions and all the other things you have downloaded on your browser so doing it in Incognito just makes it easier to figure out what's actually part of your application versus what's external to your application now the first thing I want to talk about is how JavaScript handles garbage collection because understanding that allows us to to solve a lot of memory problems automatically and the nice thing about JavaScript compared to languages like C and C++ is garbage collection handles all the memory management for you for example it'll clean up memory when it's no longer needed now in this very simple bit of code we have just a class called test and we have two objects that we're creating we're creating a test object and we're creating this string right here and both of these variables are essentially Global variables they're available everywhere in our code which means that they're never going to get cleaned up by this garbage collection because they could be used other places in our code since these are essentially Global variables but if we create a scope we could do something like inside of an if block like this or we can just create a scope by using these curly braces just like this this is going to create a scope where the variables are only accessible inside that scope so for example if I instead create some variables in here and instead of calling them Global I'm just going to call them inner there we go so now we have this inner test and this inner string you can already see they're gray out because they're never being used so let's just go ahead and console log inner test. name and we're going to console log the inner string as well just they're actually being used so JavaScript will create space for them but these variables are inside of a scope right here and they're never accessible outside that scope which means as soon as this scope is done executing these variables are automatically going to be cleaned up out of memory by JavaScript for us and you'll notice on the right hand side of my screen I have all this information this is the memory tab inside of the Chrome debugger tools and this allows us to look at every single thing that's stored in memory for our entire application it's a ton of information but it can be incredibly useful for understanding how garbage collection works as well as finding problems inside of your actual code now the easiest thing to get started with is to use this Heap snapshot essentially that just takes a snapshot of everything that's stored inside of your HEAP memory all at once it just takes a snapshot of it and shows it to you so if we click this record button right here that'll actually take the snapshot for us you'll notice we have 2.2 megabytes of information being stored and as you can see it's a lot of stuff that's showing up inside of this list of information that we have stored we have strings we have arrays we have functions I mean you can see there's almost 10,000 strings being stored a lot of these strings are essentially strings for different error messages and so on that they may need to show us but if we want to search for a specific string we have for example if I want to search for Global string I can hit contrl F that gives me this finder down here I can just type in global string and this is going to show me every single place that I have Global string Bane defined so the first thing that pops up right here is essentially all of my code this entire file is stored as a string inside of my memory so obviously that code for Global string is going to be inside this file and the next place is the actual string itself as you can see if I scroll up this is inside of the strings category there we go you can see this is inside the string category and it is storing that Global string directly inside of here so we can see that that variable is being stored and you can see exactly how much space that's taking up inside of the memory of my program so we can really see exactly what's going on down to the individual bits and bytes of your code now I know this is a lot of overwhelming information but I promise you by the end of this video this is going to make a lot more sense to you now the next thing I want to search for for is this inner string so we can come in here let's search for inner string do a little paste and we'll notice it obviously shows up right here where we've created all of our code that's this entire file but if we hit enter again you'll notice inner string is actually still stored inside of our memory right here in the strings category now that may be a little bit counterintuitive because I told you garbage collection will clean things up that are no longer needed but in this case you can see the string is still there even though it should be removed since we're outside of this scope we can actually see this even more in action if we search specifically for the class CL of test so if we search for that class of test and we open this up you notice only one thing is being stored in here that is my global test my inner test for that inner test variable we have inside the scope that is not being stored anywhere in our memory it has been cleaned up and removed and the reason that there's a difference between the way that it handles classes and the way that it handles strings is because JavaScript has two different types of values there are primitive values these are essentially strings booleans numbers all those things that are built into JavaScript and then there are objects AR and other things that are built on top of Primitives so anytime you have something like an object an array a class anything like that those are going to be garbage collected automatically but anytime you use a string a number a Boolean those will stay in memory essentially forever because they are not being garbage collected that's why the string for inner string still shows up when I actually search for that down here you can see that this is showing up here while that inner test variable is removed because this is essentially an object and objects are automatically garbage collected to show you a little bit more exactly how this is working I'm going to throw in a debugger statement right here so I'm going to put a debugger statement inside of this particular scope and I can actually show you the difference between what it looks like before and after we get to this point so I'll give this a quick save you can see we're in that debugger statement I'm going to clear out my current snapshot and create a brand new snapshot and now what I'm going to do is I'm going to search for test you notice inside of here we have three different test things inside here we have a test for Global we have another test for Global and then we have a test for inner test now the reason we have two Global tests showing up right now is just just because I'm using live server so every time I refresh my site it keeps the data from before so there may be some things where this one hasn't been garbage collected quite yet but hopefully will eventually be garbage collected you'll also notice if I search for inner string that the inner string is still showing up inside of there as well as my outer string or I called it Global string you can see that that is still showing up inside of here as well now if I were to let this code continue by just clicking the play button right here that'll let my code continue on and I go into my memory and I create a brand new snapch we should hopefully see inside of here that if I search for a test we are now back to just one single global test so this is actually really a good example of how garbage collection works you noticed back in this example when we searched for only our test class we had three different test objects and two of them were our global test that's because originally I had one global test and then I refreshed my application so it refreshed my page and I created a brand new global test but the old one was still stored in memory because it hadn't gone around and cleaned up my memory yet cuz garbage collect just happens randomly over some period of time so I had two of these global test variables both being stored then eventually a little while later when I took this second snapshot garbage collection had happened and it cleaned up both my inner test which is no longer needed as well as that original global test that again is now no longer needed since that file essentially no longer exists since I refreshed my application now the reason I'm getting this refresh behavior is because I'm using something called live server which automatically refreshes my site every time I save my files and it's doing some magic behind the scenes to make all of that work but this is essentially would work anytime like you call a function if you call a function multiple times back to back it may have multiple instances of that variable still in memory just because it hasn't gone through and actually done garbage cleanup yet with the garbage collector so that's pretty much the basics of garbage collection anytime you have an object or any other non-primitive type it's going to be removed from memory anytime it is no longer needed and there's different algorithms that are used behind the scenes to try to figure out when this thing is no longer needed but essentially you can assume whenever the code is outside of its current scope it's probably going to get garbage collected event now this big memory thing if you don't have something to search for is incredibly difficult and the annoying thing is is you can't search for objects very easily inside of here you can search for classes very easily but objects are really hard to search for so one thing that I like to do to make this a little bit more manageable on what's actually going on is I like to add a debugger statement at the very top of my file if I need to do some really complex memory management so I'm going to add that debugger to the very top of my file you can see I've hit it right here go into my memory clear everything out and create a brand new snapshot this essentially will a a lot of the generic JavaScript stuff that gets automatically created when your program actually gets started this will hopefully minimize the amount of new stuff that's being created then we can go ahead and just click continue so it runs our entire application and now we can take another brand new snapshot you notice both these snapshots have a ton of information inside of them but the really nice thing is there's a drop down up here that I can say I only want to look at the things that were allocated between snapshots 1 and two and now you can see the list of things that's much smaller and these are only the things that were given memory between the time that this debugger statement ran at the very top of my application and then after all my code ran and I actually clicked the snapshot button this is a much more manageable way to look at your code because obviously there's a lot of stuff in here automatically generated by JavaScript but I can look at this and be like okay here's my test right here that's my test variable if I look inside of string you can see I have some string information being showing up inside of there now the reason that you don't actually see global string or inner string inside of here is because those are created essentially immediately that's just kind of how JavaScript works but generally if you're dealing with memory problems it's not because of strings it's probably because of objects and other things so this gives you a really clean way to essentially look at your code and figure out what's actually happening and I love being able to go between different snapshots and using debuggers is a great way to do this for example I threw a debugger originally into this section of my code because I wanted to see what essentially was being created in this very section of my code what did the memory look like at that exact moment so debugs are a great way to actually make sure you take a snapshot exactly where you want to and then you can use this only looking at things between multiple snapshots to see exactly what happened between each snapshot now in order to talk other potential problems I want to clear this out and talk about the different types of profiling types we have these other two options are essentially the same thing this first one is allocating essentially all of your different memory across the timeline so when I click this record button it'll actually record memory uses until I click stop this one right here called allocation sampling is just a version that samples at a much lower frequency so instead of being completely up to date with exactly what memory it is at all time it just takes snapshots periodically and then Compares those snapshots to each other it's more so if you want to do something long running as as compared to this option which is much more accurate but it's much more performance intensive so it's not as good for maybe longer running tasks so I want to talk about how these can be really great specifically when you want to deal with a memory leak in your code so if your application is just ballooning and ballooning in size this will help you figure out what that problem is so what I'm going to do is I'm going to remove all of this clode so we can talk about and show how this works I'm going to come in here with a document. addevent listener I'm going to add a click event listener that takes in an object I'm going to create a variable a which is just going to be equal to a string we just come in here this is going to take our client X and it's going to say position or something it really doesn't matter what this thing does I just want to show you how this allocation instrument timeline works so what happens when my application starts up I can click this play button and you can see I have a gray bar going along every time you see blue on that bar that means there's new memory being allocated so every time I click on my document I'll just bring this over real quick every time I click on S of here you can see a blue bar showing up even when I was moving things around there was blue bar showing up because there's different like size events and so on that are happening in JavaScript to allocate all this additional memory but the main memory is from me clicking on this you can see pretty much every time that I click I get this blue bar showing up on the right hand side now I'm going to bring this back over so it's out of the way we can stop this test and we can see all the information about all the memory that was allocated during the entire time that this snapshot was running which is a really great way again to only look at memory that was created during a specific time period now I want to talk about how we can use this to actually find memory leaks inside of our code so I'm going to replace this code real quick with some code that looks like this essentially we're creating a map starting at index zero and every single 1 millisecond we're adding a brand new entry to that map and adding one to I every single time now if I give this a quick save essentially what's happening behind the scenes now is every single millisecond I'm adding a new value to a map so we can come in here we can click play and you can see right here immediately there's tons of information being stored into memory every single Blue Bar means there's more information being stored into memory and it's obviously going to constantly grow and grow and grow and grow I'll click stop on this for now and we can actually search for our map you can see there's eight Maps being stored we just need to find the one that is ours so if we open up the table we should be able to find one as soon as we get the table open that has all of our information inside of it looks like it was none of these must be this top one right here there we go you can see I open up my table and this map right here has tons of information in it if we can even look at the size of this table you can see it is massive it's 114,000 bytes of space that's being taken up compared to almost everything else that is a much smaller amount of size being stored inside of here if we look at the retained size right here 245,000 this is 10% of all the memory in our entire application is going to this one particular map so this is a great way for us to be able to detect that there's a memory leak inside of our application because you can see we're constantly allocating memory and this thing right here is constantly growing we can even do this with normal snapshots I can come in here for a keep snapshot take a quick snapshot and you can see that if I look at my retained size I search for map and we look inside here you can see 28% of my application is taken up by just this map at 924 th000 bytes now if we do another snapshot and again in search for map you can see that this is growing it's gone from 924 to 997 we take another snapshot we should see that this eventually will surpass a million so it's just constantly growing and growing so this is how we can narrow down and figure out what's actually causing memory leaks inside of our application we can see it is this map and we can find the really large map and if we look at the table for it we can see hey it's this map that has all these different index values inside of it and hopefully from there you can narrow it down inside of your code now this was actually a purposeful example of me using the map because I want to talk about how you can use a weak map instead to solve certain memory issues that you're having in your application related to possibly using Maps or sets that's because both maps and sets have a weak map and a weak set version now the only difference between the normal map and the weak map and the normal set and the weak map is that weak map will garbage collect your keys automatically for you so in our case as you can see here this keyi is no longer used ever again in our application after this point we're incrementing it by one it no longer exists so we realistic Al could remove this value from our map because we know we can never access it again now in some cases you want to have a map where you can later access it by some other means by like automatically typing in a value from a user input or something like that but sometimes you have a map where you only want to store the value and keep the value in that map if the key is essentially still around that's the case of a weak map and a weak set now a weak map and a weak set require you to use objects as the keys because those are the only things that are garbage collected so let's convert this to an object that uses this I variable inside of here instead and automatically just by doing that we should actually clean up our entire memory leak because what's happening is this object right here is being created and then it's automatically being garbage collected because it's no longer accessible outside of this particular scope we can even make this a little bit more clear by saying that this is going to be our object and we'll use this as the key right here as you can see this object is never accessible outside this scope so essentially it's setting this variable in the map and then garbage collection is automatically cleaning it up for us so we'll give that a save clear out of all of our s snot we'll go back to this allocation instrument and if we give this a quick run you can see with the snapshot recording we get no giant blue bars showing up anywhere in our application when we stop this and we look for our map and we come into here you can see right now we have that big map from before that's I think because of our way that our live reloading is working so I'm actually going to hard refresh my application to hopefully clear out everything that's inside of there and now I'm going to do another brand new snapshot and then we're going to stop that snapshot and I had to go through and do a little bit more clearing but I got all the extra data removed so now we're just left with essentially our normal application so I'm going to give this a quick save I'm going to do a snapshot start you can see there's a couple places where memory is being allocated but not too bad and if we stop and we search for map you can see that maps are taking up almost no space at all 0% and we specifically have all of our weak Maps this weak map right here is the one that we created and if we look inside the table you can see there's absolutely nothing being stored inside of our table I can even prove this by adding a specific value inside of here we're going to set this to object which say outer object is going to have a outer value and then let's create that outer object this is just something that won't be garbage collected so we'll say outer object is equal to this we'll say I is ne1 there we go now we give that a quick save do my Snapshot again give it a second to run open this up search for week map specifically we can pull up our weak map and you can see the only thing being stored in here is our outer object and then we just have a bunch of other stuff that's in the process of being deleted because as you can see it's essentially labeled as a whole which means there's no data being stored there because it's been garbage collected so the idea behind a weak map and a weak set is essentially anytime that the object that you use as the key leaves the scope of that particular map or set it's going to delete all the information related to that from the map so it's going to delete the key and it's going to delete the value while a normal map and a normal set keep all the information in them as long as possible another difference between the two is you cannot Loop through a weak map or a weak set because there's really nothing to Loop over because it only keeps in place the keys that actually exist so there's constantly data being removed from it which is why you can't Loop over it now this is a pretty Niche use case you're probably not going to use weak Maps or weak sets all that often because most of the time when you have a map or set it's because you want to keep data in their long term and reference it later by creating brand new objects or brand new values that reference those things while in the case of a weak map and a week set it's where you have to deal with data that's constantly going to be changing maybe you have a really large map and you want to make sure you automatically remove values from it that are no longer needed those are the particular scenarios where week map would be really useful now I know this is a ton of information that I covered but if you want to go even deeper into debugging best practi as an advanced debugging techniques I highly recommend you check the video right here that's an entire crash course on debugging also if you enjoyed this video where I really deep dove into how JavaScript works I highly recommend checking out my JavaScript simplified course teaches you everything you need to know about JavaScript to go from a beginner to an absolute master of web development no matter what your skill level is so if you're interested in that I'll leave a link in the description for you with that said thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 71,129
Rating: undefined out of 5
Keywords: webdevsimplified, garbage collection, js garbage collection, javascript garbage collection, javascript, js, javascript memory management, js memory management, memory management
Id: WqNqeMjd28I
Channel Id: undefined
Length: 18min 31sec (1111 seconds)
Published: Tue Jun 25 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.