I have an application which is performing some memory intensive tasks. I am trying to figure out what the total available memory is and what the available free memory is. I am doing so by using Runtime.getRuntime().freeMemory() and Runtime.getRuntime().totalMemory()
I am curious if the result I am getting is the total amount of free memory and total memory on the device or if it is the total amount of memory available to that instance of the Dalvik VM that the application is running on top of? I would appreciate some feedback. Thanks!
According to the JavaDocs, those should be in terms of the heap for your process. That being said:
getMemoryClass() on ActivityManager is a more Android-y way to determine the heap size for your process.
Because Dalvik's garbage collector is non-compacting, memory reported by methods like freeMemory() will overstate how much you can allocate. By "non-compacting", I mean that if you free up two blocks of memory that happen to be adjacent, the garbage collector leaves them as two blocks of memory. Contrast this to the Java VM, which will recognize that the two blocks are adjacent and update the heap to reflect one larger free block rather than two smaller free blocks. The non-compacting garbage collector means that your heap is more prone to fragmentation than complete exhaustion. You will try to allocate some large block and get an OutOfMemoryError, not because the heap lacks free memory, but because there is no single free block big enough for your request.
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'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.
Can you please tell me how does Dalvik memory fragmentation handling?
For example, if I have a an app allocation some small memory. but free some of them, and then later on trying to allocate a big chunk. How can Dalvik handle such request, with all the 'holes' in the heap?
I need help in understanding this from logcat:
11-15 02:50:21.837 D/dalvikvm( 990): GC_BEFORE_OOM freed 16K, 40% free 9830K/16384K, paused 90ms, total 90ms
11-15 02:50:21.837 E/dalvikvm-heap( 990): Out of memory on a 5032864-byte allocation.
It said my application has use 9830K out of 16384K. And I understand 16M is the maximum heap size, it can't grow any further.
But that should leave 6554K free (16384k - 9830K).
Why dalvik says 'out of memory on a 5032864 byte allocation. That is 4914K which is smaller that I have left.
Thank you.
Take a Look at this, It might help you to understand how to handle dalvik memory fragmentation
Link1
Like most implementations of Garbage Collector (GC), the GC of Dalvik/Java uses double references: reference variables in memory don't point directly toward their objects but toward a second reference which finally point toward the individual objects. Therefore, the GC is free to move around the memory allocations and fuses together the holes when the application need a big memory allocation without impacting in any way the various reference variables allocated by Java.
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