Memory Leak in Android

Tram Ho

The goal is to learn about Memory leak, but first of all, read about GC to understand more about Memory leak

I. Garbage collector (GC)

GC is short for Garbage collector its main effect is to free up memory for objects after they are no longer needed.
GC is very closely related to the two types of memory that we often encounter, Stack and Heap. So let’s learn these two types of memory first.

II. Stack and Heap

Simply put, the stack is used to allocate static memory and the heap to allocate memory dynamically. Let’s look at the following example

I will describe in more detail about the lines of code in the above example. Line 1: Java Runtime creates stack memory for the main method.
Line 2: Create a primitive variable, created and stored in the stack of the main method.
Line 3: Create a new object, created on the stack and stored in the heap. Stack is where the object’s reference is.
Line 4: same as line 3.
Line 5: A new block is created in the stack for the foo method (similar to line 1).
Line 6: A new object is created on foo’s stack, and the reference is passed to the heap.
Line 7: Create a String object, create in the stack and refer to the String Pool in the heap.
Lines 8 and 9: methods terminate, objects released on the stack.

And of course what happens on method completion When the foo () method completes

When the main () method completes

So the stack is freed when the methods are complete, what about the heap? The heap is different from the stack, it is not retrieved automatically when the method completes. That’s why java created a robot to free up heap memory space and that’s Garbage Collector (GC).
So why is there a leak When unused objects in the heap still have references from the stack, GC cannot free up memory?

  • So when is the object cleaned up by the garbage collector?
    An object qualifies for the garbage collector to clean up when it doesn’t have a reference to it

Like the above code, the compiler will initialize a box object and store them in the heap, then return its reference for the box variable holding. => Reference sounds familiar, but is it really getting it right? When you initialize an object with the keyword new a new object is created and stored in the heap and returns a reference. In other words, reference is the address of the object stored in the heap

III. What is Memory Leak and what causes memory leak?

1. What is memory leak?

Memory is allocated but never free. That means garbage collector can’t put them in the trash, and we can only do it when it’s put in the trash.
Initially it won’t be a problem but imagine how the memory won’t be freed for 2 weeks. Like if the user continues to use, the unused memory continues to increase and the memory Unused is not freed by Garbage collection’s garbage collection. Therefore, the app memory continues to increase until there is no available memory available for the active app => OutOfMemmoryError and finally crash app (chan)
So how do we check the memory leak in the app ?? There is a great library called LeakyCanary – a great library to help find memory leak in android.

  1. Causes and ways to avoid memory leak Surely, when mn code, there will be a case that Context param is included in the constructor, right. And its main purpose is to use to load and access resources.
    In normal apps, you will find there are 2 main types of contexts for activity and for application. And also the two params that dev often use most

As in the above code, acvtivity is being taken as the context of Textview which means that the view will refer to the entire main activity, so your activity will be kept tight and can not be recovered by GC
=> leading to memory leak (and leaking all activities is very easy if you are not careful)

  • Let’s consider the next case. When the screen orientation changes (screen rotation), the system will:
  • As defined, it will destroy current activity and initiate a new activity while the state is preserved. Doing so means that android is loading the UI of the application from the resource. Now imagine you are writing an application with a very large bitmap and you do not want to reload while rotating the screen. And the simplest way is to retain the state of activity is to use the static variable. Please review the following example:

The above code is very fast but also very wrong (chan). It leaks right from the first activity when initialized and then rotates the screen. When the drawable attaches to the view, the view will be set as a call back on the drawable. As in the code above, this means the drawable has a reference to the textview which itself has a reference to the activity (context). The code above is the simplest example of a context leak.
There are two easy ways to avoid memory leak caused by context

  • Method 1: Avoid escaping the context outside of its scope Example: Let’s review the above example. Reference of a static variable, but implicit references and implicit references to outer classes can be dangerous like together
  • Method 2: Use application context. Application context will continue to live as long as your application is alive and independent of the activity life cycle
    In short to avoid memory leak caused by context
  • should not keep a reference to the context-activity that lives too long (a reference to the activity must have the same life cycle as the activity itself)
  • Instead of using activity-context should use application context => Explanation: if using activity-context only attaches to an activity and when that activity destroys the reference of the context to that acrivity still remains and is not collected by GC If in case there are many activities, the more activity-context is not cleaned => the easier it will lead to memory leak. Instead of using the application context, it is attached to the application’s life process, when the application is in backgound, the application context is not revoked by GC will only have 1 reference is the application

2. Other subjective causes of memmory leak

To say that memory leak occurs just because of context is not enough. And below are some of the other reasons I can synthesize for your reference
2.1 Broad cast receiver Have a look at the following scenario:
First you register a local broadcast receiver in the activity.
If you do not unregister broadcast receiver and then it still keeps the reference of the activity because for you already closed that activity => and of course the memory to save the reference of that activity increased and not released => Memory leak is here but where

Workaround: Always unregister receiver in the onStop () of the activity
Note: If the broadcast receiver is declared in onCreate (), when the app goes into the background and then comes back to the resume, the receiver will not be registered again. And that’s always good
= >> so it is best to register in onStart () or onResume () of activity and unregister in onStop ()

2.2 Static activity or view reference
Let’s see the example below

You declare 1 TextView as a static.
If the reference of the activity or view, directly or not directly from a static reference, the activity will not be revoked after being destroyed.
If the activity or view is declared static, then when the activity is destroyed, it will not be able to recover the memory allocated to that view and activity.
Workaround: Never use static variables for activities, views, or contexts.
2.3 Singleton class reference Let’s recall a little what Singleton pattern is
Singleton Pattern is one of the simplest design patterns in Java. This type of design pattern belongs to creational pattern which means that singleton pattern provides the simplest way to create an object
As shown in the diagram below, the Singleton Pattern will refer to a class whose class is responsible for instantiating an object and ensuring that only one object is instantiated

Return to Singleton Class
Singleton class is the class in which there is a return instance method of the object itself and the special thing is that this method must declare static.
See the example below, you need to define a singleton class as the code below

Add the parameter context to the instance of SingletonSimpleclass => why is causing memory leak problem in this case Solution 1: Instead of passing param context, switch to param application context option 2: if you still want to Use the pass parameter context when the activity is destroyed, make sure that the context you entered in that param has been set to null.

Reference links
https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html
https://android.jlelse.eu/9-ways-to-avoid-memory-leaks-in-android-b6d81648e35e http://keirik.com/index.php/2020/03/23/memory-leaks-in -android-tat-all-ve-no /

Share the news now

Source : Viblo