If I have understood correctly, an android process has two heaps - one managed by the VM and one native.
The size of the VM heap cannot exceed 16mb (at least, this value can be higher on some phones).
But what about the maximum size of the native heap?
The 16 mb limit doesn't seem to be a hard limit in that an app can allocate more than 16mb through the NDK, but the OS will start killing other processes and possibly the foreground process as well when a high amount of memory is used.
When does the OS start behaving this way? When the native heap + VM heap size exceeds 16mb?
Debug.getNativeHeapSize() gives the size of the native heap, but is there a function to check the combined native + VM heap size?
Curious to hear from someone who knows how this works!
There is no "line of death" in Android memory management. When the system needs to kill processes to reclaim memory, it considers a number of different factors, including the process' importance (determined by factors like whether or not it's in the foreground, or providing services to a foreground app) and how much memory it's using.
If your process is idle, and sitting on more memory than anything else, it's likely to be killed first.
The exact algorithm has evolved a bit over time, and the system doesn't make any guarantees about specific behavior.
Related
I'm sorry for asking this duplicate question. But as you can see in that link the topic is saying one thing but the content is about something else.
I'm not asking how to manage or how to monitor the memory, just want to know how much memory usage you call a memory friendly app. And from what range you consider as using too much memory.
Thank you
Short Answer: As low as possible.
Long Answer: To allow multiple running processes, Android sets a hard limit on the heap size alloted for each app. The exact heap size limit varies between devices based on how much RAM the device has available overall. If your app has reached the heap capacity and tries to allocate more memory, the system throws an OutOfMemoryError, and to avoid running out of memory, you can to query the system to determine how much heap space you have available on the current device.
You can query the system for this figure by calling getMemoryInfo(), which provides information about the device's current memory status, including available memory, total memory, and the memory threshold—the memory level at which the system begins to kill processes.
For more details, see this
https://developer.android.com/topic/performance/memory
As I researched, Android allocates limit memory for each process, maybe range from 16MB to 24MB for each one. Here is reference
Nevertheless when I view memory usage for one application in setting, I often see one normal application costs hundred megabytes for memory (on one process). There is a conflict here that I cannot understand.
Thanks :)
NDK code can use more system RAM than can a single Dalvik/ART process. Also, the app might be using more than one process, or it might be using android:largeHeap to request an above-normal heap size.
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 using Galaxy Nexus(i9250) for development and testing. I noticed strange fact- sometimes when the total heap size is 64mb and allocated heap size is in and around 56-60mb, app crashes. But sometimes I noticed that even the memory shoots up to 80mb, app didn't crashes.
Initially I thought that maximum heap size for devices of the range nexus will be 64mb(now I realize it is wrong). So my question is what is the maximum heap size a device can use. If it is variable based on device, then on what factor heap size depends. I knew this is a common question. Could anyone guide me to the right answer. Thanks in advance!
NOTE: I didn't use LargeHeapSize = true; in my code
Considering , your app crashes every time giving "OutOfMemoryError"
DVM starts by allocating a small heap, after every garbage collection cycle it checks for free heap and compares it to the total heap memory and adds more memory in case that the difference is too small. So Heap can be increased or decreased at runtime as per Dalvik VM's requirement by OS.
So, when their is enough memory available in the system your app didn't get crashed when the memory shoots up to 80mb.(Assuming 64MB is not the hard limit of heap size)
Yes there is a hard limit on the heap size of every device which can be increased by using "LargeHeapSize = true" , but this might be too costly in terms of app performance as increased heap size is directly proportional to the time taken by the garbage collection process(as GC now have to traverse more objects inside bigger heap). So it is a big "NO,NO" until unless you exactly know what and why are you going for larger heap size.
on what factor heap size depends:
Heap size mainly depends on the resolution of the device you are
using, as more resolution needs larger images/bitmaps size to fit
in.(more pixels = needs more memory to incorporate)
Although, I didn't got through any written proof of this.. As per my
understanding Heap size also depends on the RAM size. Since, bigger
RAM size will allow more flexibility of multitasking and lesser
chances of getting the "OutOfMemoryError"
In case you needs to know exact amount of heap memory you can use, ActivityManager.getMemoryClass(). This method returns an integer indicating the number of megabytes available for your app's heap
ActivityManager.getLargeMemoryClass() for larger heap size
it is not clear that what device you are exactly talking about. It is also not clear how you calculated your heap memory.
I recommend you calculate your heap memory and available memory using this link
But if your app uses Native Memory, their are no restriction on that link.
I would only use the DDMS values as a guide to find memory leaks and memory allocation problems rather than some specific number given that you can target. Any Android application will be expected to run on a variety of devices so while you may have tuned your app for a 'Galaxy Nexus' you will want to be able to run on older devices, and test appropriately. See
#dongshengcn comment.
In addition to the links by #minhaz I would also read: Understanding Heap Size.
If you are trying to get a better understanding of memory management on Android then you should read Android Framework Engineer #hackbod's answer to: How to Discover Memory Usage of My Application in Android.
The size of the VM heap cannot exceed 16mb, 24mb, 32mb depending on the phone.
But what is the maximum size of the native heap? How much native memory can be allocated to the app when it is in foreground.
Thanks.
Technically there's no restriction in the NDK. Someone asked this a while back and was referred to this android-ndk Groups thread. A relevent quote:
"Also given that this is the NDK list, the limit is actually
not imposed on you, because it is only on the Java heap. There is no limit on
allocations in the native heap..."
Dianne Hackborn
She does go on to say that it shouldn't be abused and if it is than applications could be killed.
There's no simple answer to this; you can use as much memory as the device has, minus what it's using for other programs. When Android thinks it's low on memory, it'll start killing background tasks, so it's a soft limit. Most devices do not have swap space. You can get some statistics about the device's memory from inside Dalvik with android.app.ActivityManager.MemoryInfo (I assume there's an NDK equivalent).
adb shell dumpsys meminfo PACKAGENAME will give you native and dalvik memory usage of your app.