SlideShare uma empresa Scribd logo
1 de 12
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
Android Out of Memory Error:
Causes, Solution and Best practices
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
Out of Memory (OOM) Error
Out of memory error is very common error when you are developing an application that
deals with multiple images sets or large bitmaps or some Animation stuff. In this case
we have to be very careful and efficient while handling the images or object allocation
and de-allocation. OOM error comes when the allocation crosses the heap limit or your
process demand an amount of memory that crosses the heap limit.
In Android, every application runs in a Linux Process. Each Linux Process has a Virtual
Machine (Dalvik Virtual Machine) running inside it. There is a limit on the memory a
process can demand and it is different for different devices and also differs for phones
and tablets. When some process demands a higher memory than its limit it causes an
error i.e Out of memory error.
Possible Reasons:
There are number of reasons why we get Out of memory errors. Some of those are:
1. You are doing some operation that continuously demands a lot of memory and at
some point it goes beyond the max heap memory limit of a process.
2. You are leaking some memory i.e you didn’t make the previous objects you
allocated eligible for Garbage Collection (GC). This is called Memory leak.
3. You are dealing with large bitmaps and loading all of them at run time. You have to
deal very carefully with large bitmaps by loading the size that you need not the
whole bitmap at once and then do scaling.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
The biggest reason for Out of memory is a Memory leak. First let us see a memory leak
examples.
Examples:
1. We make an Activity and create a TextView with Activity context and set a sample
text in to it.
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
setContentView(label);
}
This means that views have a reference to the entire Activity and therefore to anything
your activity is holding onto; usually the entire View hierarchy and all its resources.
Therefore, if you leak the Context (“leak” meaning you keep a reference to it thus
preventing the GC from collecting it), you leak a lot of memory. Leaking an entire activity
can be really easy if you are not careful.
2. When the screen orientation changes the system will, by default, destroy the current
activity and create a new one while preserving its state. In doing so, Android will reload
the Application’s UI from the resources. Now imagine you wrote an application with a
large bitmap that you don’t want to load on every rotation. The easiest way to keep it
around and not having to reload it on every rotation is to keep in a static field:
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
ImageView label = new ImageView(this);
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
This code is very fast and also very wrong; it leaks the first activity created upon the first
screen orientation change. When a Drawable is attached to a view, the view is set as
acallback on the drawable. In the code snippet above, this means the drawable has a
reference to the ImageView which itself has a reference to the activity (the Context)
which in turns has references to pretty much anything (depending on your code.).
Now if the orientation changes the Drawable will not come under GC because it is static
and due to this the ImageView will also not go under GC operation because the
Drawable is linked to the ImageView by the Drawable callback and same for Activity
context becauseImageView was created with Activity context. So this lead to a memory
leak and every time you change the orientation this leak will grow in the heap and at
some point it will increase the heap limit and android will kill the application and throw
Out of memory error.
Tools to Diagnose OOM
In Android there are some tools that can be used to find the memory leaks and one of
them is MAT (Memory Analyzer Tool). This can be used as a plugin to Eclipse or as a
standalone tool.
Let’s start with installing MAT and using it with Eclipse with a step by step guide:
1. To start up with this tool you have to download this tool from following
link:http://www.eclipse.org/mat/downloads.php
2. Start Eclipse and run your application.
3. Go to DDMS and select your application and click the Dump HPROF file button and
it will ask you to save the hprof file. Save it on your hard disk.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
4. Run the MemoryAnalyzer.exe file situated in the MAT package downloaded.
5. This MAT tool will not understand the hprof file generated by Eclipse so you have to
convert it using the hprof-conv tool in the tools folder of android-sdk using the
following command:
hprof-conv com.example.android.hcgallery.hprof mat.hprof
6. Now this file is ready to use with MAT.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
How to analyze the Heap dump in MAT?
Case Study
While doing Android app development, I got Out of memory error. In the following
example I will share my problem statement and the way I found the leak and how I
resolve it.
Problem Statement:
I was dealing with multiple Drawables that are used in AnimationFragment class to do a
frame animation and it was working fine as long as I didn’t check the heap while rotating
the device. Every time I was rotating the device the Activity restarts as to load a new
layout for landscape mode and then heap grows and this keep on going and then I fall
in to OOM error.
Reason:
Actually there was a context leak in my Fragment and every time I rotate the device the
previous Context is not destroyed because the Drawable used in the
AnimaitonDrawable class were still holding a callback to the AnimationDrawable that in
turn stops the Activity to get destroyed or to get collected by the GC.
How I found the reason?
1. I took a dump for my application and convert it using hprof-conv and then open the
file “mat.hprof” in MAT.
2. Go to overview option and check the Top consumer option and it will look like
following:
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
This diagram will tell you about the allocation and the space occupied by every object
(widget, drawables, bitmaps etc). Using this you can check which objects are taking
more memory than you can look at the code and attack them first. In my case it was
AnimationDrawable.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
There are two heaps shown in the diagram let’s see them first:
Shallow heap: This is the size in bytes that is actually taken by the variable.
Retained heap: This is the size of the variables with whom this variable is maintaining
reference.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
For A, the shallow heap is 100 but the Retained heap is 300 because it is holding 300
bytes of memory to be collected by GC.
In the 2nd image we can clearly see that the AnimationDrawable objects are the biggest
objects in the heap. So we should target AnimationDrawable first. To see the actual
object and its location click on the respective row and go to ListObjects -> with incoming
reference and then you will see the following window.
Expand this entry to see all the objects and in this case the entries are:
Retained Heap is more important for finding leaks, as it is the total size of all objects
being kept alive by this dominator. To get this number, MAT needs to calculate the
Retained Size by following all object references. As sorting by Retained Heap is very
helpful for finding leaks, MAT displays the largest retained heaps in a pie chart.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
The selected ones are the objects in my code which are having high retained heap
value and the entries are shown with package name and class name. Now you exactly
know where are the objects that are taking the most of memory and you can recheck
that code.
Solution:
I checked my code by using the MAT reference and then I realize this
AnimationDrawable is not getting destroyed and because of this the frames in it are also
becoming a part of the leak. So, I clear all the callbacks of AnimationDrawable as soon
as the Fragment is destroyed and after this heap was stable and when orientation
changes the heap decreases as the Drawables got destroyed and then increases for
the new allocation.
There can be a no. of reasons for an OOM but the main reasons mostly ends in a Leak.
So if gets closer to the leaks then you can easily get rid of OOM.
Getting a Heap dump at runtime:
When you are getting a OOM error and you want to check the heap and allocation when
the error comes than you can add some code that will catch OOM error and then calling
the Debugger to dump the Heap from our code. Let me show you an example to do this:
1. Make an OOM error Listner as an inner class that will
implement Thread.UncaughtExceptionHandler
public class MyActivity extends Activity {
public static class MyUncaughtExceptionHandler implements
Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if(ex.getClass().equals(OutOfMemoryError.class))
{
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
try {
android.os.Debug.dumpHprofData("/sdcard/dump.hprof");
}
catch (IOException e) {
e.printStackTrace();
}
}
ex.printStackTrace();
}
}
2. In your Activity’s onCreate set a listener on the current thread that will catch the OOM
error
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.currentThread().setDefaultUncaughtExceptionHandler(new
MyUncaughtExceptionHandler());
}
}
In this way you can check the heap dump at the point when OOM occurs.
| Build a Mobile Experience www.innovationm.com
Corporate Office:
InnovationM Mobile Technologies
E-3 (Ground Floor), Sector-3, Noida 201301 (India)
t: +91 8447 227337 | e: info@innovationm.com
Best practices to avoid memory leaks or OOM
 Do not keep long-lived references to a Context / Activity (a reference to an
Activity should have the same life cycle as the activity itself).
 Try using the context of application instead of a context of activity.
 If you are using a large bitmap as background or something in your application
than don’t pull the full image in to the main memory. You can use the insample
size property of bitmap to bring the size your screen needs.
 Memory fragmentation: You should plan the allocation of the variables so that
after deallocation the memory should not be scattered or fragmented. If 10 MB
memory is available in chunks and process requests for 2 MB and couldn’t find a
chunk of 2 MB then it will ask for more heap and this in turn can cause OOM.
 Sending large files to server should be done in chunks because loading a large
image in bytes can cause OOM.
 A activity that is using so many images should remove the callbacks to the
drawable used by calling setCallBack(null) on the drawable to avoid OOM.

Mais conteúdo relacionado

Mais de InnovationM

Mais de InnovationM (20)

How to use data binding in android
How to use data binding in androidHow to use data binding in android
How to use data binding in android
 
Capture image on eye blink
Capture image on eye blinkCapture image on eye blink
Capture image on eye blink
 
Mob x in react
Mob x in reactMob x in react
Mob x in react
 
How to use geolocation in react native apps
How to use geolocation in react native appsHow to use geolocation in react native apps
How to use geolocation in react native apps
 
Android 8 behavior changes
Android 8 behavior changesAndroid 8 behavior changes
Android 8 behavior changes
 
Understanding of react fiber architecture
Understanding of react fiber architectureUnderstanding of react fiber architecture
Understanding of react fiber architecture
 
Automatic reference counting (arc) and memory management in swift
Automatic reference counting (arc) and memory management in swiftAutomatic reference counting (arc) and memory management in swift
Automatic reference counting (arc) and memory management in swift
 
Firebase crashlytics integration in iOS swift (dSYM File Required Problem Res...
Firebase crashlytics integration in iOS swift (dSYM File Required Problem Res...Firebase crashlytics integration in iOS swift (dSYM File Required Problem Res...
Firebase crashlytics integration in iOS swift (dSYM File Required Problem Res...
 
How prototype works in java script?
How prototype works in java script?How prototype works in java script?
How prototype works in java script?
 
React – Let’s “Hook” up
React – Let’s “Hook” upReact – Let’s “Hook” up
React – Let’s “Hook” up
 
Razorpay Payment Gateway Integration In iOS Swift
Razorpay Payment Gateway Integration In iOS SwiftRazorpay Payment Gateway Integration In iOS Swift
Razorpay Payment Gateway Integration In iOS Swift
 
Paytm integration in swift
Paytm integration in swiftPaytm integration in swift
Paytm integration in swift
 
Line Messaging API Integration with Spring-Boot
Line Messaging API Integration with Spring-BootLine Messaging API Integration with Spring-Boot
Line Messaging API Integration with Spring-Boot
 
Basic fundamental of ReactJS
Basic fundamental of ReactJSBasic fundamental of ReactJS
Basic fundamental of ReactJS
 
Basic Fundamental of Redux
Basic Fundamental of ReduxBasic Fundamental of Redux
Basic Fundamental of Redux
 
Integration of Highcharts with React ( JavaScript library )
Integration of Highcharts with React ( JavaScript library )Integration of Highcharts with React ( JavaScript library )
Integration of Highcharts with React ( JavaScript library )
 
Serialization & De-serialization in Java
Serialization & De-serialization in JavaSerialization & De-serialization in Java
Serialization & De-serialization in Java
 
Concept of Stream API Java 1.8
Concept of Stream API Java 1.8Concept of Stream API Java 1.8
Concept of Stream API Java 1.8
 
How to Make Each Round of Testing Count?
How to Make Each Round of Testing Count?How to Make Each Round of Testing Count?
How to Make Each Round of Testing Count?
 
Model View Presenter For Android
Model View Presenter For AndroidModel View Presenter For Android
Model View Presenter For Android
 

Último

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Android Out of Memory Error - by InnovationM

  • 1. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com Android Out of Memory Error: Causes, Solution and Best practices
  • 2. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com Out of Memory (OOM) Error Out of memory error is very common error when you are developing an application that deals with multiple images sets or large bitmaps or some Animation stuff. In this case we have to be very careful and efficient while handling the images or object allocation and de-allocation. OOM error comes when the allocation crosses the heap limit or your process demand an amount of memory that crosses the heap limit. In Android, every application runs in a Linux Process. Each Linux Process has a Virtual Machine (Dalvik Virtual Machine) running inside it. There is a limit on the memory a process can demand and it is different for different devices and also differs for phones and tablets. When some process demands a higher memory than its limit it causes an error i.e Out of memory error. Possible Reasons: There are number of reasons why we get Out of memory errors. Some of those are: 1. You are doing some operation that continuously demands a lot of memory and at some point it goes beyond the max heap memory limit of a process. 2. You are leaking some memory i.e you didn’t make the previous objects you allocated eligible for Garbage Collection (GC). This is called Memory leak. 3. You are dealing with large bitmaps and loading all of them at run time. You have to deal very carefully with large bitmaps by loading the size that you need not the whole bitmap at once and then do scaling.
  • 3. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com The biggest reason for Out of memory is a Memory leak. First let us see a memory leak examples. Examples: 1. We make an Activity and create a TextView with Activity context and set a sample text in to it. @Override protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); setContentView(label); } This means that views have a reference to the entire Activity and therefore to anything your activity is holding onto; usually the entire View hierarchy and all its resources. Therefore, if you leak the Context (“leak” meaning you keep a reference to it thus preventing the GC from collecting it), you leak a lot of memory. Leaking an entire activity can be really easy if you are not careful. 2. When the screen orientation changes the system will, by default, destroy the current activity and create a new one while preserving its state. In doing so, Android will reload the Application’s UI from the resources. Now imagine you wrote an application with a large bitmap that you don’t want to load on every rotation. The easiest way to keep it around and not having to reload it on every rotation is to keep in a static field: private static Drawable sBackground; @Override protected void onCreate(Bundle state) { super.onCreate(state); ImageView label = new ImageView(this); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label); }
  • 4. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com This code is very fast and also very wrong; it leaks the first activity created upon the first screen orientation change. When a Drawable is attached to a view, the view is set as acallback on the drawable. In the code snippet above, this means the drawable has a reference to the ImageView which itself has a reference to the activity (the Context) which in turns has references to pretty much anything (depending on your code.). Now if the orientation changes the Drawable will not come under GC because it is static and due to this the ImageView will also not go under GC operation because the Drawable is linked to the ImageView by the Drawable callback and same for Activity context becauseImageView was created with Activity context. So this lead to a memory leak and every time you change the orientation this leak will grow in the heap and at some point it will increase the heap limit and android will kill the application and throw Out of memory error. Tools to Diagnose OOM In Android there are some tools that can be used to find the memory leaks and one of them is MAT (Memory Analyzer Tool). This can be used as a plugin to Eclipse or as a standalone tool. Let’s start with installing MAT and using it with Eclipse with a step by step guide: 1. To start up with this tool you have to download this tool from following link:http://www.eclipse.org/mat/downloads.php 2. Start Eclipse and run your application. 3. Go to DDMS and select your application and click the Dump HPROF file button and it will ask you to save the hprof file. Save it on your hard disk.
  • 5. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com 4. Run the MemoryAnalyzer.exe file situated in the MAT package downloaded. 5. This MAT tool will not understand the hprof file generated by Eclipse so you have to convert it using the hprof-conv tool in the tools folder of android-sdk using the following command: hprof-conv com.example.android.hcgallery.hprof mat.hprof 6. Now this file is ready to use with MAT.
  • 6. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com How to analyze the Heap dump in MAT? Case Study While doing Android app development, I got Out of memory error. In the following example I will share my problem statement and the way I found the leak and how I resolve it. Problem Statement: I was dealing with multiple Drawables that are used in AnimationFragment class to do a frame animation and it was working fine as long as I didn’t check the heap while rotating the device. Every time I was rotating the device the Activity restarts as to load a new layout for landscape mode and then heap grows and this keep on going and then I fall in to OOM error. Reason: Actually there was a context leak in my Fragment and every time I rotate the device the previous Context is not destroyed because the Drawable used in the AnimaitonDrawable class were still holding a callback to the AnimationDrawable that in turn stops the Activity to get destroyed or to get collected by the GC. How I found the reason? 1. I took a dump for my application and convert it using hprof-conv and then open the file “mat.hprof” in MAT. 2. Go to overview option and check the Top consumer option and it will look like following:
  • 7. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com This diagram will tell you about the allocation and the space occupied by every object (widget, drawables, bitmaps etc). Using this you can check which objects are taking more memory than you can look at the code and attack them first. In my case it was AnimationDrawable.
  • 8. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com There are two heaps shown in the diagram let’s see them first: Shallow heap: This is the size in bytes that is actually taken by the variable. Retained heap: This is the size of the variables with whom this variable is maintaining reference.
  • 9. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com For A, the shallow heap is 100 but the Retained heap is 300 because it is holding 300 bytes of memory to be collected by GC. In the 2nd image we can clearly see that the AnimationDrawable objects are the biggest objects in the heap. So we should target AnimationDrawable first. To see the actual object and its location click on the respective row and go to ListObjects -> with incoming reference and then you will see the following window. Expand this entry to see all the objects and in this case the entries are: Retained Heap is more important for finding leaks, as it is the total size of all objects being kept alive by this dominator. To get this number, MAT needs to calculate the Retained Size by following all object references. As sorting by Retained Heap is very helpful for finding leaks, MAT displays the largest retained heaps in a pie chart.
  • 10. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com The selected ones are the objects in my code which are having high retained heap value and the entries are shown with package name and class name. Now you exactly know where are the objects that are taking the most of memory and you can recheck that code. Solution: I checked my code by using the MAT reference and then I realize this AnimationDrawable is not getting destroyed and because of this the frames in it are also becoming a part of the leak. So, I clear all the callbacks of AnimationDrawable as soon as the Fragment is destroyed and after this heap was stable and when orientation changes the heap decreases as the Drawables got destroyed and then increases for the new allocation. There can be a no. of reasons for an OOM but the main reasons mostly ends in a Leak. So if gets closer to the leaks then you can easily get rid of OOM. Getting a Heap dump at runtime: When you are getting a OOM error and you want to check the heap and allocation when the error comes than you can add some code that will catch OOM error and then calling the Debugger to dump the Heap from our code. Let me show you an example to do this: 1. Make an OOM error Listner as an inner class that will implement Thread.UncaughtExceptionHandler public class MyActivity extends Activity { public static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { if(ex.getClass().equals(OutOfMemoryError.class)) {
  • 11. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com try { android.os.Debug.dumpHprofData("/sdcard/dump.hprof"); } catch (IOException e) { e.printStackTrace(); } } ex.printStackTrace(); } } 2. In your Activity’s onCreate set a listener on the current thread that will catch the OOM error @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Thread.currentThread().setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); } } In this way you can check the heap dump at the point when OOM occurs.
  • 12. | Build a Mobile Experience www.innovationm.com Corporate Office: InnovationM Mobile Technologies E-3 (Ground Floor), Sector-3, Noida 201301 (India) t: +91 8447 227337 | e: info@innovationm.com Best practices to avoid memory leaks or OOM  Do not keep long-lived references to a Context / Activity (a reference to an Activity should have the same life cycle as the activity itself).  Try using the context of application instead of a context of activity.  If you are using a large bitmap as background or something in your application than don’t pull the full image in to the main memory. You can use the insample size property of bitmap to bring the size your screen needs.  Memory fragmentation: You should plan the allocation of the variables so that after deallocation the memory should not be scattered or fragmented. If 10 MB memory is available in chunks and process requests for 2 MB and couldn’t find a chunk of 2 MB then it will ask for more heap and this in turn can cause OOM.  Sending large files to server should be done in chunks because loading a large image in bytes can cause OOM.  A activity that is using so many images should remove the callbacks to the drawable used by calling setCallBack(null) on the drawable to avoid OOM.