Memory Leak

What is a memory leak?

Memory Leak is an object which is application is no longer using, but the Garbage Collection fails to recognize them as unused. The result is that they stay resident in the memory heap.Taking up valuable space that’s never freed for other objects.

Garbage Collection in android

When the amount of memory allocated to app reaches an upper limit a garbage collection event kicked off to free any resource that might no needed.The garbage collector tries to collect everything that is not a GC route  So, if you create an object and remove all references to it, it will be garbage collected, but if you put it in a GC route like a static field, it won’t get garbage collected.onDestroy() is called, it’s going to be garbage collected soon.

Memory Heap in Android

Memory is segmented up into separate spaces based upon what type of allocation is occurring.When allocations in any of the spaces grow a GC event can be kicked off in order to make more room for future allocations.GC event can stop the app events(Quickly eat up app frame time).

Each space has a set of size is allocated.GC keep track or the combined size.As a new object is allocated the of object characteristic are taken into account to best fit what space it should be placed into.

View leak

One of the worst things that can get leaked in your android application is a view object.By themselves, views aren’t much of a leak problem.Rather it’s what they reference that can cause a horrible leak situation.

Views contain a reference back to the activity that created them and activity in turn to reference lots of internal objects and other memory items.This is why a leaked view object is such a big issue.

When the user rotates their device, configuration change will be triggered, causing the current activity to be destroyed.and a new instance of it to be loaded into memory.

But if a view from that first activity was leaked, then the original activity can’t be cleaned up now

How to avoiding leaking view object?

1.Don’t reference view inside of async callbacks.That async event may execute at some point in the future where things aren’t ideal.

2.Don’t reference views from static objects.The issue here is that static objects persist for the lifetime of the entire process that’s running your app, which by the way, is not the same as the lifetime of the activity that declares the static object.As such, having a static object reference to a view can cause issues when the activity is destroyed.

3.Avoid putting views in collections that don’t have clear memory patterns.For example using a WeakHashMap object to store view as values.Since WeakHashMap store view as hard references, you can end up in a bad spot anytime something destroys those views.This type of  WeakHashMap behavior has led it to be nicknamed the leak hashmap.

Why is memory leak bad?

GC event can stop application code from executing in order to properly clean up any resource, that is not being used anymore.Performance problems here come from the fact that missing the memory in your app.These events to kick off that’s heating up your frame time anytime your frame drips about the 16ms second barrier user are going to start to notice.

Memory Churn

Improperly using memory can still kick off a load of performance problems.Allocating too many objects in a short time frame is a clear problem that you should be aware of.Memory churn is when a high number of objects are allocated and potentially freed in a small amount of time.

The quick allocation of so many objects effectively pollutes the recently allocated objects space with a flood of reserved memory blocks.

If you’re noticing in the memory monitor that you’re getting a flood of GC events in a very short time frame then this point to a high chance.

Typically memory churn comes from creating a whole group of a temporary resident object like image or view paint.they repeatedly get created exist a little while and then are freed.This action ends up polluting and fragmenting the memory heap in a very short amount of time resulting in more GC event being kicked off.

Prevent Memory Leak

Allocating new objects in the middle the nested loops or onDraw function of your view.Now the solution here is pretty simple picture code but in order to do that, you need to know where exactly thing is going wrong.

Using memory monitor tool will give you a sense of how your memory working over the lifetime of your application. Every time you see a dip in the allocated memory that see a GC event occurring lots of dips in a really short time frame signals a huge problem.So, for every GC event that you can avoid your app has more time per frame.

A weak reference is a way to access that object without increasing the number of references to it. If there are no more strong references to that object, the weak reference will also be cleared. So, if we make our activity a weak reference, and if at some point we realize the weak reference is cleared, it means that the activity has been garbage collected. However, if it isn’t cleared, we likely have a leak that merits investigation.

The main purpose for weak references is for caches, where they are very useful. They are a way to tell the GC to keep something in memory, but that it can clean them if no one else is using them.

LeakCanary: Detect all memory leaks!

LeakCanary is an open source library that can help put a stop to memory leaks.Instead, we want to focus on how we can detect the leak earlier as it happens while we’re developing the app. That’s where LeakCanary comes in.

How LeakCanary Work?

LeakCanary attaches a pin to things like my Android collectible. The pin knows whether they have been garbage collected or not, and after a while if the pin realizes that it is still not in the trash, it takes a picture of the memory – a heap dump into the file system.LeakCanary then publishes the result so that we can see the memory leak.

We can view the chain of references that are holding the object in memory and preventing it from being garbage collected.

what is going to happen is in for every single leak the top part is always going to object that should be in memory and the bottom part is always going to object that should not be in memory.The key part for you is to identify each of the two zones it’s not going to interleave so top is always green the bottom is always red and the place where it changes is where there’s a bad reference that you need to kill and if you kill bad reference then the object is not connected to GC route anymore and the whole thing can be garbage collected.

Analyzing the Heap

LeakCanary takes all that memory and dumps it to a file, which we then open with a tool to analyze and parse the heap dumps. One of these tools is Memory Analyzer. It basically has all the live objects and classes that were in memory when you took the heap dump. It has a query language called SQL, so you can write something like:

This will give you all the instances where destroyed is true. Once you have found the leaking activities, you can do something that’s called merge_shortest_paths, which computes the shortest paths to the GC root. This will find the backward paths to the objects that are preventing your activity from being garbage collected.

I mention “shortest path” specifically because there are multiple paths from a number of GC routes to any activity or object. For example, my button’s parent view, which also holds a reference to the mContext field.

When we look at a memory leak, we don’t need to look at all the paths; we just want the shortest one. That way, there is less noise, making it easier to find the problem.

LeakCanary Implementation

LeakCanary has a library to parse heap dumps, and implementing it is fortunately very easy. LeakCanary opens the heap dump, load it, parse it, and then find our reference based on the key.LeakCanary obtains that instance, and then just need to parse the graph of objects, work backward, and find the leaking reference.

All that work is actually happening on the Android device. When LeakCanary detects that an activity has been destroyed but not yet garbage collected, it forces a heap dump that gets put on the file system. It then starts a service in a separate process, which will analyze the heap dump and publish the results.

You get is a notification and when you tap it on the notification you get following screen

What is going on a method that nothing gets garbage collected because the entire group of an object is held in memory. The static a singleton here it’s called it’s called a GC root.That’s what I’ve shown as the gray box it’s something that’s never going to be garbage collected.It’s a reference that is never cleared. You could think of static fields you can also think of local variable on threads or references held by native code like a binder.

So, if you wanted to figure out why it’s leaking we have to find a path from those yellow boxes to the activity it’s called a path to GC routes all. In the java memory usually, end up with an infinity of path because there are so many objects that are connected together so you could look at like ten thousand path that’s not very helpful what’s more helpful is if there is let’s say there is only one.

There is one that is the shortest path that is guaranteed to go through that bad reference so it instead of looking at 10,000 paths we can just look at one.we’re going to look at the shortest because that’s’ less information to deal with.

Detecting Memory Leaks Using LeakCanary

Here is an example of a memory leak we found in AsyncTask. Suppose we have an app with the long running task. We have an activity, and at some point, you click on a button and rotate the device.

add the following dependencies in your app build.gradle.

In your Application class:

Create an activity with one Button which is use for executing long running task.

 

The thing here is an activity and onDestroy has been called by android on that activity. So we know that it’s useless at that point and that nothing really needs a to use it and it shouldn’t be in use but it’s still you know holding lot of memory and we want it to be garbage collected and so that activity is held in memory because there’s good pass there’s a bunch of references that eventually reference the activity and that’s why it’s kept in memory the activity is leaking

LeakCanary gives kind of a textual way now this is interesting we identify the object on the path there are supposed  to still be in them in memory and the objects are supposed to be gone and it’s not just going to be one for example maybe top green one is the application class it should stay around forever because identify one should be in memory and one should be not in memory. We can sort of splits are the paths in sort of two area and we can identify the connection creating a problem all

 

Related Post

Firebase Performance Monitoring for Android

Crashlytics

Leave a Reply

Your email address will not be published. Required fields are marked *