Memory Leaks on Android

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video I'm gonna talk about memory leaks on Android and before I get started with the specifics of what I'm gonna be talking about I just want to mention that if you don't know what memory leaks are or you're kind of unsure about them you don't know a lot about them this video is gonna be very very valuable because chances are if you don't know about them you don't know a lot about them you're probably gonna have a lot of them in your code specifically speaking in this video I'm going to be talking about what exactly memory leaks are why you want to avoid memory leaks the most common ways that memory leaks can occur coding patterns that typically lead to memory leaks I think that was four things four or five and then I'm gonna finish up by showing you some practical examples of causing memory leaks and then how to identify memory leaks so that you can then go into your code and figure out what's wrong and fix them so the first question is what exactly is a memory leak and to understand memory leaks first of all you need to understand memory and how its managed on Android so the Android device has a fixed amount of memory it's no different than your computer or any other tech device there's always going to be some amount of memory that that device has and can use at any given time things that use up memory are objects threads or any process that the Android device is going to do that means like starting a new application declaring new objects and stanching objects all that all that stuff requires memory and there is a fixed amount of it this fixed amount of memory is known as the heap H EA P it's spelt heap and the heap on an android device basically denotes the amount of free memory at any given time so I like to think of it as a pile of a pile of memory blocks for example every time something is done that requires memory a block or a memory block is removed from the pile otherwise known as the heap and that is then being used for something so if I was to instantiate an object I would take a memory block away from the heap and then that memory block is then used for that object to prevent the Android system from getting overwhelmed when it's under heavy load or when a lot of memories being used or in other words when the heap is low when it's low on memory there's something called the garbage collector the Android system has something called a garbage collector and it's the garbage collectors job to basically go around the device it can access any application any process and to look at it and see which objects which processes which threads are no longer needed and then it wants to and then it will take the resources that those things are occupying and return it to the heap so it's essentially it goes around and it collects memory blocks that are no longer being used and then puts it back into the free resources pile that's how I like to think of it anyway and the garbage collector operates completely independently of everything else it's part of the Android system it has a built in algorithm that the the people who design the Android system have programmed and it's designed to go off it has an algorithm built in it goes off and does its own thing basically this isn't something that the developer that you as the developer can control not directly anyway it kind of goes off and does its own thing and frees up resources that it it thinks need to be reclaimed so now I'm sure you're wondering how does this garbage collector thing relate to memory leaks and it's actually pretty much directly related to memory leaks because a memory leak is defined as when the garbage collector is unable to reclaim a resource and return it to the heap so if an object is instantiated a memory block is taken from the heap and for whatever reason that garbage collector is not able to then reclaim that block of memory and return it to the pile that's when you get a memory leak so now that you know what a memory leak is or kind of what a memory leak is let's talk about the most common ways that these can occur how does this how does this happen how is a built-in function known as the garbage collector unable to essentially perform its job so there's several ways that you can get memory leaks but some of the most common ways are due to a view a context or an activity reference saved on a background thread so the reason that causes a memory leak is in an example for in the example of an async task for example if I was to save a context reference to to the async task to some custom async task and then I was to use that context reference to instantiate an object maybe like a bitmap or something like that which is what we're gonna do in the example and in a couple minutes here that will essentially keep a reference to the context in the background thread and then if that activity is destroyed that async task is still running in the background so what happens if the activity is destroyed the garbage collector goes up to clean up the activity but it's eased that there is a reference saved to that activity in some of the threads so it's unable to clean it up because it sees that there's a reference pointing to it from some other thread and that's that's kind of the most common way that mmm really can occur so in general before we look at the example here just if you don't want to watch this video anymore and you're getting bored in general to avoid memory leaks you're probably like avoid 99.9% of memory leaks that you could ever have happen to your code don't save context or activities or views on background threads and you'll probably be good but if you want to learn more we're gonna take a look at an example here that I've prepared and look at kind of this in more detail okay so what I'm gonna be doing in this short demo is I'm gonna take you through a couple examples of things that are going to cause memory leaks and then I'm going to show you how you might detect them go about detecting them so to get started we need a way to detect memory leaks and I think the best way that I've seen out there is to use an open source library known as leak Canary it's very easy to set up it's very easy to use and it works really really well it's made by the company known as Square which is a very well renowned company so let's go down here and I'm at the github page Philly Canary if you want to get to it you can know it's just Google leaked Canary and I'm sure it'll be like the first one that comes up right there so just scrolling down on the github page here and I'm going to the getting started guide and I'm going to grab these two Dependencies this is for using support library fragments which we're not going to so we're just going to grab these two and I'm going to open up Android studio and I'm going to paste that in down here and sync the project now if I go back to the github page I have a couple more steps here the first is to actually this is the last step is to create a class that extends application and then all I'm gonna do is put this little bit of code in there and everything will just work it's it's really that straightforward all I need is together dependencies create this class and then when the app starts it's just going to work which is really a beautiful thing so I'm going to go into the main package directory I'm going to right click go to new Java class I'm just going to call this my application and I'm going to extend my application like it says on the github page it's giving me a warning here which is telling me I need to add this to the manifest so when we go to the manifest I want to add a name attribute to the application and reference that new class that I just made so that's added now I just want to paste in that oncreate method that's from the github page and I'm ready to go now when I run the app leak canary will automatically start and it's going to detect memory leaks if one occurs in the app so as you can see it's very very easy to set up and you're gonna see it's really really powerful and easy to use too in just a few minutes here okay so we're done in the application class we're done in the build up Gradle now I want to talk about the app that we're going to be working on so it's very simple I just have one activity it's got a button with an ID go on it which is going to start the async task that we're going to add to the activity so pretty simple going into main activity there's nothing here yet so all I did so far was attaching onclicklistener to the go button and then there's gonna be some code in here that we're gonna execute okay so like I said we're gonna be building an async task to cause these memory leaks so I'm gonna create a private class I'm going to call it my async task extend by async task and they're all going to be void this is just kind of a dummy class where I'm forcing memory leak it's giving me a warning so I'm gonna go alt enter implement the doing background method and I'm also going to insert the default constructor I'm pressing alt insert getting that default constructor there is our async task I'm going to declare it as a global object so my async task let's call my async task and then inside the on click method I'm going to start that async task but before I do that we need to alter it just a little bit here so if you were watching if you're paying attention to the beginning part of this video you know that saving a reference to a view and activity or a context into something that runs on a background thread is a big no-no that's what's probably going to lead to you having memory leaks so what I'm going to do is just that I'm going to do the thing that I told you not to do so I'm going to add a context variable to the async task and I'm going to pass it through the constructor so context context and I want to go M context equals context and then inside the doing background method I'm going to instantiate an object that uses that context so I'm going to instantiate a bitmap object it's a bitmap factory and I want to decode resource I'm just going to decode a drawable so here's what I'm going to reference the context get resources and I want to just reference that and then r dot drawable dot I see launcher background so it's just a default image that comes in your project just this image right here it doesn't matter what image you use just any drawable will be fine and now what I'm going to do is I'm going to sleep the thread for a period of time so sleep I'll sleep it for 5,000 milliseconds it's giving me a warning here I'm just gonna press alt enter surround that in a try-catch and we are ready to go so so what I'm going to do is I'm going to start the async task then the bitmap will get instantiated and before the thread is finished sleeping so it's gonna sleep in five seconds before it's done finished finished sleeping I'm going to destroy the activity and so that is what's going to cause the memory leak because as you know the memory leak will occur will be triggered I guess you could call it when the garbage collector is unable to clean up a resource or something that's been assigned a block of memory and that can happen when a background or when a reference to an activity of you or context is saved on a background thread so if I destroyed the activity but the async task still holds a reference to that activity or that context the garbage collector is not going to be able to clean up the async task and so that's what we're going to see here so inside of the go method here I'm going to instantiate my new async task so new my async task it's going to take a contact so main activity this and then I want to call my async task dot execute and that's going to execute the async task so that's going to start it now I need a way to destroy the activity so what I'm going to do is right here write a little if statement saying if my async task does does not equal null meaning it's already started because the first time I click it it's going to assign the async task and execute it but when I click the Go button the second time this will no longer be null so this if statement will run and what I want to do is I want to finish the activity so let's go into result in the activity being destroyed and you can confirm that by inserting the on destroy method and I can just write a little log that says activity is destroyed so I need a tag to just typing log T for the tag and there we go so yeah now I'm going to run it and we'll take a look so while it's while it's getting ready to run I'm just going to kind of summarize once again what's gonna happen I'm gonna click the Go button this if statement will not run because the async task will be no so the async task will get instantiated it will execute the bitmap will get instantiated inside the doing background method the thread will go to sleep for five seconds before that five seconds is up I'm going to press the Go button again which will result in the activity being destroyed so at that point what we're gonna have is a context saved on a background thread in this bitmap object and the activity is being destroyed so we should see a memory leak alright so I have the app open here I'm gonna press go and I've waited about a couple seconds now and if I go again you can see the activity is destroyed and now in a few seconds you should see a little notification up here from leaked Canary there it is right there and if I pull that down it's saying dumping hee analyzing heap dump and what's going to happen is it's going to give me some information about what's happened here basically if you get a notification it means you have a memory leak if you don't get any notification you mean it means that you have no memory leaks so you can see that I have a leak here I can get some information on it it's saying that I have some thread then my async task object is referencing a context and there's an issue here so it's tell it's pointing here and saying that this is the issue there's some kind of an issue here basically go fix it you can see the red underline the red underline that's that's how we canary works so if I was to remove this for example actually I guess we can just now I'm just gonna go through how I would the different ways I would resolve this memory leak so the first way is actually what I can do in the ondestroy method before a super Don destroys called I can go my sync task cancel and set this to true so what that's going to do is it's going to interrupt the background running task and stop it and shut it down basically so because the issue here is that this async task exists and it holds a reference to the activity the activity gets destroyed with the async test just still exists and holds that reference the reason it still exists is because this doing background method is running so what we can do is we can cancel it and interrupt it if it's running and then destroy the activity and everything should be fine so I'll run that and I'll show you that there will be no more memory leak all right I'm gonna press GO that's a couple seconds now and if i skogen the activity is shut down now I'm just waiting to see if I can get a notification from leak canary and nothing is showing up as you can see it would have shown up by now so that solves our problem that's one way to solve the problem although I still wouldn't recommend saving that's kind of like a workaround I guess I still I wouldn't recommend saving a context in general on a background thread but if you do just make sure that you clean up your resources before the activity is destroyed so the garbage collector can do its thing so the next method that we're going to look at is using something known as a weak reference and if you use so if you use a weak reference weak reference object actually I'm just gonna write it out and then we'll talk about it here so weak reference context alcohol also is call it em context comment this out you know em context equals new week reference and I want to pass the context and then inside here instead of writing this just going to duplicate that line in case you don't know what shortcut I just use to copy that line it just press control D and so now I'm going to go context dot get and what that's going to do is this is actually a weak reference object and I can reference the type by calling get so you can see that returns a context object and that should be fine so that I can comment this out too so you can see that the weak reference is taking care of that issue but before I run it I've got to do one last thing I need to declare the async task as static I need to declare it as static because this is currently an inner class that's defined inside of main activity because this async task is an inner class inside main activity it has an implicit reference to that activity so by declaring it as static I get rid of that implicit reference so yeah that should take care of it we have our weak reference in here we're using that to build our bitmap and it should be good to go got our cancel method commented out now I'm gonna run it and I'll show you that there should be no memory leak all right I'm going to press GO and then press GO again I think I just press it the first time and I press the second time there we go and let's wait to see if we get a notification from leaked canary and it seems to be all good so so far nothing I'll just give it a couple more seconds that looks good to go so the weak reference took care of that memory leak issue another thing to note about this static declaration is watch what happens when I actually add this context to here so Oh I'll comment this one out comment that out comment that out comment that out and turn this all back it's giving me a warning here it says this field leaks a context object if I delete the static reference it gets rid of that warning but then I get another warning up here so either way you're gonna get a warning if you use static it basically tells you that this is potentially going to cause a memory leak and then you need to look at this so a good rule of thumb that I like to you is either don't use a context reference inside a background thread at all ever which is the best way to do it or declare it as static because that way at least you're going to get a warning from Android studio and it's going to tell you hey you might want to look out here this is probably going to cause an issue so that's it for this video hopefully it was helpful and you have some new insights into memory leaks and how you can prevent them yeah so thanks for watching and I'll see you in the next video you
Info
Channel: CodingWithMitch
Views: 40,268
Rating: undefined out of 5
Keywords: android tutorial, memory leaks android, memory leaks on android, what is a memory leak?, what is a memory leak, android memory leak, how to detect memory leak, how to find memory leaks, leak canary, leakcanary, android memory, finding memory leaks android, finding memory leaks, memory leaks, leaking memory android, android memory leaks tutorial, android memory leaks example, how memory leaks occur, how to find memory leaks in android studio
Id: bNM_3YkK2Ws
Channel Id: undefined
Length: 18min 35sec (1115 seconds)
Published: Sat Jan 05 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.