Android Does my app have a memory leak? - android

I was looking at the memory usage in android studio and noticed that every time I launch my app, the memory increases by a few MB. I've never got a OutOfMemory exception crash report from any of my supported devices. I'm not familiar with a lot of the tools included in the android sdk so I'm not sure if this signifies a memory leak or not.
In the android studio memory monitor, this is what the graph looks like after 3 launches:
As you can see, the memory increases a few MB each launch.
Does this mean I have a memory leak?
If so what steps can I take to find the source of the memory leaks?

To make sure your app doesn't have memory leaks you need to do two things:
Make a heap dump.
Analyze it with some memory analyzer.
The way to obtain a heap dump is described in the official documentation.
Once you have your dump, you can load it into the memory analyzer tool (I prefer YourKit, but you can pick up any analyzer you like) and look for leaked objects (the steps to do it can be found in the documentation of chosen memory analyzer).
Simple YourKit workflow: start the analyzer, open the heap dump via Ctrl + O. You'll see the screen similar to attached below:
Click the Inspections button on the left side and then Alt + A (or Run All button). The inspection you're interested in is Objects retained by inner class back references contained within Possible leaks group. Here I have only String objects, which can be considered normal. Any time you see here some of your own classes, you have a memory leak. You can click on your objects (if you have them listed here) to see which references it has and who references it to understand what's the leak source.

Related

How to read a profiler .hprof memory heap dump in Android Studio?

I am in desperate search of a memory leak and I was wondering how to read my memory heap dump:
Does that for example mean, that MainActivity is active twice? Or only that it's in the backstack twice?
Why would my TrackingService be called twice? It gets activated at startup and then basically forgotten by the rest of the app.
What's up with ChooseLoginRegistrationActivity? Is it in the backstack 3 or 5 times? What are the two weird Lambda activity? ChooseLoginRegistrationActivity is always finished with finish() after a ´startActivity()`, should it even pop up here at all?
When I call finish() on an activity, will the memory allocated to that activity be freed up with the next iteration of the garbage collector? Because when I call the gc manually in the profiler, the memory wasn't released, and waiting didn't help either. Going to the desktop of my smartphone released like 50% of my apps memory, and going back to the app didn't claim the memory back.
A bit late, but you may find using Eclipse MAT useful. You can create a heap dump from Android Studio Profiler and convert it into standard .hprof in order to import it into Eclipse MAT.
In Android\Sdk\platform-tools (to have access to the hprof-conv tool available that converts the dump), open a terminal and type the command
hprof-conv AS-name.hprof EclipseMAT-name.hprof
This will generate a converted file with your given EclipseMAT-name name which you can use to import a proper standard heap dump into Eclipse MAT.
After importing into MAT you can see an overview of your memory at the given heap and can even get custom reports for Leak Suspects which may bring you closer to the culprits of those terrifying OOM errors.
LeakCanary can also prove useful for finding these pesky errors.
Hope this might help you and anyone else with finding memory errors.

Added memory in android monitor Memory management in android

I have this application that, once I go through, there is approximately 4mb that gets added once redirected to the home page(home activity).
I have bitmaps and I do release them, I nullify all member variables at the onDestroy. I have used the GC in the android studio but it does not come back to around the same memory size of the first time that activity was called.
The process of my application is :
Login -> Home -> Image Capture -> Summary (click done at this point to return to Home)
Doing so add's approximately 4mb every run of this flow in the android monitor when you are back to the Home activity.
Is this normal, am I missing something? I have tried with leakcanary but I have not received anything from it(and yes I know its setup because I get the initial access request).
I think this is ridiculous because someone can use this application for 10times or maybe 20 000 times before resetting it and 20 000x 4mb that is way too big.
While LeakCanary can be useful to find some memory leaks, I've found that Android Studio's tools are better (in my humble experience). I recommend you use the Android Studio's HPROF Analyzer to try and find your leak.
Go to the Memory Monitor do the chain of events that cause a leak and then click the Dump Java Heap button. After it's done it should automatically open your dumped heap snapshot. There, on the top right you should see the Analyzer Tasks tab, click it and run a memory leak detection.
Unfortunately without some code to look at this is the best advice I can give you.

Memory usage analysis using Android Studio

I am trying to understand where my app is using memory, and where I can make it more efficient in this respect.
In the Android Monitor part of Android Studio, I have dumped the Java Heap, and am looking at the generated hprof.
And I see a lot categorized under FinalizerReference:
What is this? How can I understand better what is causing it, and how to keep it down? Looking into the "Instance" panel doesn't help me much... doesn't make much sense.
I have tried looking at this but it's all slightly over my head at the moment.
Also, at the moment the memory monitor is reporting (in the live chart section) an Allocated memory of 10.58 MB. But on my device, in Application Manager > Running Processes, my app is showing a memory usage of 44MB. Why the discrepancy? If it's the ~33MB I want to try and reduce, I'm not apparently even seeing that in Android Studio, so no real hope of identifying what it is?
There may not be much you can do about FinalizerReference memory usage. See this question for more details - basically some objects implement finalize() and these are handled a little differently, such that they can end up sticking around longer. I haven't looked into it too closely, but I suspect that some android sdk objects do this and there's little you can do about it except for maybe tuning up your object caching/recycling to reduce it.
I'm not sure if this would help with FinalizerReference, but one thing I like to do to track down memory leaks is to find suspicious objects' connections to the GC root.
If you're using the Eclipse hprof analyzer (independent of the actual Eclipse IDE; works with hprofs generated by android studio), this is one way to access this:
Overview
Histogram
Right-click, "List Objects"
Right-click an object you suspect is leaking, "Path to GC Roots"
Now you should see a list of nested references leading back down from the gc root to your object.
I'm not exactly sure what is owing to the discrepancy - here is a similar question on that. Apparently the memory monitor tool may only be reporting heap allocations made by Java code, whereas the device reports the entire processes's memory usage.
The Retained Size reported by the Memory Profiler for FinalizerReference is currently a meaningless number, as I argued in my answer to my own similar question.
To summarize: Treating FinalizerReference like any other class when profiling (as Memory Profiler does), leads to repeated counting of the same memory when calculating its Retained Size.
I view this as a bug in Android Studio's Memory Profiler, and have filed this issue.

Potential memory leak of bitmap reported by heap analysis tools but no bitmaps used by App

My App is running fine (i.e. no crashes). During testing I have been investigating memory use. I use Android Studio (AI-141.2006197) DDMS to output a Dump HPROF file then open it in the Eclipse Memory Analyzer. This tool describes a leak suspect:
One instance of "android.graphics.Bitmap" loaded by "<system class loader>" occupies
2,536,984 (40.81%) bytes. The memory is accumulated in one instance of "byte[]"
loaded by "<system class loader>".
Keywords
byte[]
android.graphics.Bitmap
Some more information from the dominator_tree:
Over the last day I have stripped the opening activity and fragment of my App to bare bones, removing all opening and reference to bitmaps, removing menus, service, everything. All that's left is one activity containing 1 fragment. The fragment has a ListView, with each list item having a simple TextView. No bitmaps are used. I can show the code in a later edit to this question if needed.
I am testing this stripped-down App on a phone and a tablet. I install the App, start it, see the list displayed by the first fragment, then exit. Via DDMS I cause a GC then do the heap dump and examine it in the Eclipse memory Analyzer. For both the phone and the tablet I see the "potential" memory leak.
My test phone, which uses a cynogenmod ROM, has a performance setting option to "Allow Purging of Assets" (see http://pocketnow.com/2012/12/10/5-nexus-4-speed-tips#toc-5). When I enable this feature my potential memory leak disappears. This makes me think there isn't a problem with my App after all, but its some system behaviour that I don't understand.
Some questions:
Is this likely a memory leak in my App?
If my test App is not using bitmaps or drawables, why is memory for a bitmap be allocated? What can I check?
Do you have any words of wisdom regarding interpreting which potential memory leaks reported by the Eclipse memory Analyzer can be ignored?
Thanks in advance. I come from an embedded real-time C background so get very nervous when I see memory leaks!
This bitmap is system-related and not a memory leak in the App. I came to this conclusion via posts Android EdgeEffect appears to allocate a 1 meg bitmap and Strange Bitmap using 1 Mb of Heap.
For anyone reading this I'd like to bring to your attention another very useful post that showed me how to view the bitmaps that are pointed to by the Eclipse Memory Analyzer tool. This can really help with debugging. See MAT (Eclipse Memory Analyzer) - how to view bitmaps from memory dump
All views generate bitmaps caches of themselves. This is likely a memory leak. It seems to occur when there are frequent layout changes on the view. You could try to disable the cache to see if it resolves your issue:
view.setDrawingCacheEnabled(false);

How heap memory allocation works

I'm working on an app and I have memory issues.
I started to study this thing and I have met Eclipse's debugging system.
I use DDMS's Heap tester to see how much memory my app allocated.
I saw it's about 90%.
Now I made a simple new project, a blank empty activity without any functions or variables. Just a splendid new project.
I ran this heap tester and I saw the results:
Heap size: 10,629 MB
Allocated: 9,189 MB
Free: 1,440 MB
Used: 86.45 %
Objects: 44,565
Well, is it normal?
I have a very simple blank activity, and nothing else, and this app is used 86% of memory?
Allocated 9 MB of 10? Really? Is that normal? How this works?
Please instruct me about this, because I would like to know how these memory allocations work.
Dalvik will initially allocate a certain heap size to your app. In your case, this is around 10 MB. As your app needs more memory, Dalvik will increase the heap size upto the maximum configured size (which is different for different devices). If your app still needs more memory after the maximum is reached, then it will cause a OutOfMemoryException.
To learn more about analyzing memory allocations in Android, check out this excellent article from the Android developers blog:
http://android-developers.blogspot.in/2011/03/memory-analysis-for-android.html
Examining Heap Usage is somewhat tricky but is equally easy. Let's find out how.
So consider a small application. You have Android debugging tools to determine the heap usage and to examine them.
You can check this- memory-analysis-for-android, which have more details of how to analize the application effectively in android.
Let's have a short description here too:
There are two ways to start DDMS-
1) Using Eclipse: click Window > Open Perspective > Other... > DDMS
2) or from the command line: run ddms (or ./ddms on Mac/Linux) in the tools/ directory
Then select your application process from Devices and click "Update Heap".
Now switch to the Heap tab in DDMS.
To see the first update, click the Cause GC button.
You will see something like this:
We can see that our set (the Allocated column) is a little over 20MB. If you do some little flip flop, that number can go up. In small applications, the amount of memory we leak is bounded. In some ways, this can be the worst kind of leak to have, because we never get an OutOfMemoryError indicating that we are leaking.
You can use Heap Dump to identify the problem. Click the Dump HPROF file button in the DDMS toolbar and save the file wherever you want. Then run hprof-conv on it.
Using MAT which is a powerful Memory Analyzer tool-
You can install MAT from SITE which is a stand-alone Memory Analyzer tool and analyze the Heap dumps using it.
NOTE:
If you're running ADT (which includes a plug-in version of DDMS) and have MAT installed in Eclipse as well, clicking the "dump HPROF" button will automatically do the conversion (using hprof-conv) and open the converted hprof file into Eclipse (which will be opened by MAT).
Start the MAT and load the converted HPROF file. Navigate to the Histogram view which shows a list of classes sortable by the number of instances, the shallow heap (total amount of memory used by all instances), or the retained heap (total amount of memory kept alive by all instances, including other objects that they have references to).
If we sort by shallow heap, we can see that instances of byte[] are at the top.
Next, Right-click on the byte[] class and select List Objects > with incoming references. This produces a list of all byte arrays in the heap, which we can sort based on Shallow Heap usage.
Pick one of the big objects, and drill down on it. This will show you the path from the root set to the object - the chain of references that keeps this object alive. Lo and behold, there's our bitmap cache!
MAT can't tell us for sure that this is a leak, because it doesn't know whether these objects are needed or not -- only the programmer can do that. However, looking at the stats it is predictable to know that the cache is using a large amount of memory relative to the rest of the application, so we might consider limiting the size of the cache.
Go this way all along for all, and you will see a tremendous amount of performance optimization.
What you see here is allocated memory and not maximum memory which can be allocated, maximum memory which can be allocated depends upon android version and device to device.
In this case, your apps does not have any high memory requirement, all the files,system and object being used to run the app is very small hence initially android has allocated your app a common initial space,now this space goes on increasing as demand from app increases until its met, or it exceeds maximum heap size defines per app by android, in this scenario your app will crash stating running out of memory as reason.
To read more about memory allocation in android go through below developer link
http://developer.android.com/training/articles/memory.html

Categories

Resources