I'm having trouble finding good information about garbage collection in Android.
I don't really understand when you have a memory exception
Here's a question:
When I run my application and monitor it with the Android Device Monitor
I see that the allocated memory is 8 MB when the application has just started.
There's a button that creates an object each time it's pushed.
So when i keep pushing the button, the allocated memory grows until
it reaches the heap size. When the heap size is reached, the allocated
memory goes back to 8 MB but the heap has grown a little bit. After that,
this whole thing happens again and the heap keeps growing
Do i have a memory exception in this case? or is it normal that
the heap size keeps growing?
The heap size is sort of reserved memory you can use. The allocated memory is the actual memory in use.
When the allocated memory is nearing the heap size, and you see the allocated memory drop, objects are being garbage collected. The heap size will grow a bit, since you probably need more memory than currently reserved.
In the end, if you keep allocating memory without releasing it, the heap size and allocated memory will grow, until the system runs out of memory (for your application). At that point, an OutOfMemoryException will be thrown, and your app will crash.
Read Managing Your App's Memory | Android Developers for a deeper insight.
Related
I have created an Android app and I now want to make sure that it never goes above 16MB of heap usage.
Unfortunately for this task my device has a much bigger heap than the minimum of 16MB, it has at least 32MB.
When I track the allocations it just keeps allocating and allocating and seldom garbage collects which makes it hard to track down memory leaks.
I have tried to use various profilers but it is not easy.
Preferrably I would like to back and forth between activities and just see the heap go up and then back down so that there are no memory leaks but since the garbage collection is postponed until it is really needed this seems hard to do.
Is it possible to limit the heap size to 16MB on a 32MB heap size device for testing purposes?
The best way to do this is to use an Android Virtual Device, as you can configure the heap size in the Android emulator. It is in the advanced options when creating an AVD.
However if you must test this on a real device you can simulate having a smaller heap by creating a memory leak of heap memory on startup. Make sure you keep a strong reference to the object you allocate so it isn't garbage collected.
On a device with 32MB heap size, if you create a 16MB leak on startup this will leave the remaining 16MB of heap space for your application to use.
I am planning to hunt any memory leak in my Android App. After searching through different blogs, it seems like MAT is a good tool for that.
Before proceeding further, I just want to make something clear. When I check allocated heap memory in memory monitor tab of android studio, i can see the allocated memory increases by ~1 MB (from 16MB of initial allocation) each time I rotate my device. This, most probably suggests some leaks.
However in the process, at any stage, whenever I click on Garbage Collection button in memory minitor window to force GC, the allocated memory comes down to near the initial stage 16MB+ (sometimes requires 2 back to back click when allocated memory expands beyond 30 MB).
My question is, does this behavior suggests that I don't have any leaks due to strong references? If GC can collect those extra chunks, how important is that to check the issue?
For several apps that I have tested, it seems that the Heap memory usage is quite high even at the start of the application. For example, I have an app that is supposed to show an image from assets on an ImageView. But, even before loading the image, used Heap, is about 95%. When I load and display the image, it still fine, it increases used memory to about 98%. But, if I create a copy of the bitmap, then app crashes with out of memory error.
Again, my main question is why the amount of free memory is so low right at the start of an application, before any processing is done.
The reason you are seeing such high amount of memory usage percentage is because the heap hasn't grown to its maximum size. This means that even though you see 98% of usage that refers to your current heap size and not the total amount that you can use.
At runtime, the heap grows dynamically as Dalvik VM needs more memory. It is common that you start with a relatively small heap and with each GC if needed Dalvik will request more memory.
Now for your OutOfMemoryError it can be a lot of things. I would suggest sampling your bitmap at runtime using the BitmapFactory class inSampleSize
hello i m doing some runtime calculation for getting NativeHeap memory and allocated memory at runtime, so any one can suggest me
what should be the difference between "Debug.getNativeHeapAllocatedSize()" and "Runtime.getRuntime().totalMemory()"
so can prevent app by OutOf Memory Exception.
Thanks
Runtime.getRuntime().totalMemory()
Returns the total amount of memory which is available to the running program.
getNativeHeapAllocatedSize()
For devices below HoneyComb most of the huge allocations are deferred to the native heap (e.g Bitmaps). Hence this api is useful to find out how much of native heap is allocated.
OOM Errors occurs when there are no objects which can be freed by the DVM. Typically you have about 16MB in the Heap to play with (for a standard phone). Check your logs* to see GC statements having info about how much of memory is allocated.
I don't think there should be a fixed ratio to cause an OOM error. Like in the case when you load a very huge bitmap, here the native memory used is huge.
Slide 25
I have an application which creates a series of Bitmaps. I am holding these Bitmaps in SoftReferences, to avoid running out of memory. I would like the heap size to grow to the maximum 16MBs before it starts collecting my SoftReferences. However, the SoftReferences are collected very eagerly, prior to growing the heap to it's max. Is there anyway to force the references to be collected less eagerly? or to manually grow the heap to the max? Possibly a way to just start the application with 16mb allocated?
There is currently no way to modify the SoftReference collection behavior.
I'm not sure what you mean by "manually growing the heap to the max".
If these are instances of the Bitmap class (as opposed to some custom bitmap implementation), the pixel data is actually stored on the native heap, but uses an annoying "external allocation" accounting trick, which complicates the situation further. (Notably, the storage is freed by a finalizer, not the GC, and finalizers have to execute in a separate thread after the GC completes. It's possible to allocate Bitmaps until you run out of memory, and the GC has no way to release the memory before throwing an OOM error.)
It's a known issue in Andriod. When VM collects soft references, it either collects all or none, although it should collect 'some' and should not collect anything when there is plenty of free heap.
Check: http://code-gotcha.blogspot.com/2011/09/softreference.html