Android Heap Size on Different Phones/Devices and Os Versions

Android heap size on different phones/devices and OS versions

Does anyone know if the heap size on Android phones is a constant value according to what is set in the OS version or if this is a setting which the phone producers can decide on?

Technically, it is a setting which the phone producers can decide on. Android is open source. I do not recall the Compatibility Definition Document spelling out heap size requirements, though I haven't looked recently.

Is the heap size proportional to the amount of RAM on the phone?

No, it tends to be based more on screen resolution, as higher-resolution screens tend to want to manipulate larger bitmaps, so Google makes heap size recommendations that, hopefully, device manufacturers will abide by.

I've only found articles where people say that the heap size of an application is 16M.

Searching StackOverflow on [android] "heap size" turns up this answer.

Is there a minimal heap size for Android versions?

ok, i've finally found the answer (thanks to this post) :

the bare minimal for all versions of android (including 5) , is 16MB.

the requirements for each of the android versions can be read about here:

http://source.android.com/compatibility/downloads.html

you can read about them by opening the CDD files and searching for "Runtime Compatibility" (or "Virtual Machine Compatibility" for old versions). also, you can find the minimal RAM requirement by searching for "Memory and Storage", but i think it's only the requirement for the system itself.

so, for example, on 4.0.3 - 5 the minimal heap size is:

  • 16MB: small/normal with ldpi/mdpi, or large with ldpi
  • 32MB: small/normal with tvhdpi/hdpi, or large with mdpi
  • 64MB: small/normal with xhdpi, or large with tvdpi/hdpi, or xlarge with mdpi.
  • 96MB: small/normal with 400dpi, or xlarge with tvhdpi/hdpi
  • 128MB: small/normal with xxhdpi, or large with xhdpi
  • 192MB: small/normal with 560dpi, or large with 400dpi, or xlarge with xhdpi .
  • 256MB: small/normal with xxxhdpi, or large with xxhdpi
  • 288MB: xlarge with 400dpi
  • 384MB: large with 560dpi, or xlarge with xxhdpi
  • 512MB: large with xxxhdpi
  • 576MB: xlarge with 560dpi
  • 768MB: xlarge with xxxhdpi

I can't find the minimal heap size for versions 3.x but it's probably the same as 4.0.3 .

for 2.1 - 2.3 , the minimal heap size is :

Device implementations with screens classified as medium- or
low-density MUST configure Dalvik to allocate at least 16MB of memory
to each application. Device implementations with screens classified as
high-density or extra-high-density MUST configure Dalvik to allocate
at least 24MB of memory to each application. Note that device
implementations MAY allocate more memory than these figures.

meaning:

  • medium screen or ldpi - 16MB
  • hdpi or xhdpi - 24MB

i can't find the minimal heap size for version 1.6 , but it's probably the same as 2.1 .

also, i can't find out what should the large-heap flag do for each of the android versions (since 3.0) .

App Memory Usage differs between Devices

Samsung has additional layer of libraries for their custom UI on Android, which will eventually lead the app to consume more memory.

Moto devices have stock/native Android.

Your variables and objects take x memory in both devices, but your UI elements take more memory in Samsung in comparison to moto device.

examplel: If stock android uses Button class, Samsung will extend the Button class to make SamsungButton class which will have additional features (like water droplet sound on click).

Android Understanding Heap Sizes

When you set the VM budget on your emulator/device, what you are doing is telling the heap the maximum size it is allowed to be. At runtime, the heap grows dynamically in size as the Dalvik VM requests system memory from the operating system. The Dalvik VM typically starts by allocating a relatively small heap. Then after each GC run it checks to see how much free heap memory there is. If the ratio of free heap to total heap is too small, the Dalvik VM will then add more memory to the heap (up to the maximum configured heap size).

That being said, the reason why you are not seeing "24 mb" on your DDMS screen is because the heap hasn't grown to its maximum size. This allows Android to make good use of the already small amount of memory that is available on handheld devices.

As for why your application is crashing on the emulator and not your phone, that does seem odd (are you sure the numbers are correct?). You should keep in mind, however, that memory is managed dynamically and that total memory utilization is determined based on a number of external factors (the speed/frequency at which garbage collection is performed, etc.).

Finally, for the reasons I mentioned above, it would be difficult to say for sure how well your application manages memory based on the single line of information you provided above. We'd really need to see some of your code. OutOfMemoryErrors are definitely worth worrying about, however, so I'd definitely look into your application's memory usage. One thing you might consider is to sample your bitmap images at runtime with calls to inSampleSize using the BitmapFactory class. This can help reduce the amount of memory required to load your drawable bitmaps. Either that or you could reduce the resolution of your drawables (although 20 kb each sounds fine to me).

Do Android devices use different amounts of heap and footprint for the same app

There are lots of differences between Android 2.x and Android 4.
An example is how bitmap memory is managed:

On Android Android 2.2 (API level 8) and lower, when garbage
collection occurs, your app's threads get stopped. This causes a lag
that can degrade performance. Android 2.3 adds concurrent garbage
collection, which means that the memory is reclaimed soon after a
bitmap is no longer referenced.

On Android 2.3.3 (API level 10) and
lower, the backing pixel data for a bitmap is stored in native memory.
It is separate from the bitmap itself, which is stored in the Dalvik
heap. The pixel data in native memory is not released in a predictable
manner, potentially causing an application to briefly exceed its
memory limits and crash. As of Android 3.0 (API Level 11), the pixel
data is stored on the Dalvik heap along with the associated bitmap.

Quoted from:
http://developer.android.com/training/displaying-bitmaps/manage-memory.html

Detect application heap size in Android

There are two ways to think about your phrase "application heap size available":

  1. How much heap can my app use before a hard error is triggered? And

  2. How much heap should my app use, given the constraints of the Android OS version and hardware of the user's device?

There is a different method for determining each of the above.

For item 1 above: maxMemory()

which can be invoked (e.g., in your main activity's onCreate() method) as follows:

Runtime rt = Runtime.getRuntime();
long maxMemory = rt.maxMemory();
Log.v("onCreate", "maxMemory:" + Long.toString(maxMemory));

This method tells you how many total bytes of heap your app is allowed to use.

For item 2 above: getMemoryClass()

which can be invoked as follows:

ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass();
Log.v("onCreate", "memoryClass:" + Integer.toString(memoryClass));

This method tells you approximately how many megabytes of heap your app should use if it wants to be properly respectful of the limits of the present device, and of the rights of other apps to run without being repeatedly forced into the onStop() / onResume() cycle as they are rudely flushed out of memory while your elephantine app takes a bath in the Android jacuzzi.

This distinction is not clearly documented, so far as I know, but I have tested this hypothesis on five different Android devices (see below) and have confirmed to my own satisfaction that this is a correct interpretation.

For a stock version of Android, maxMemory() will typically return about the same number of megabytes as are indicated in getMemoryClass() (i.e., approximately a million times the latter value).

The only situation (of which I am aware) for which the two methods can diverge is on a rooted device running an Android version such as CyanogenMod, which allows the user to manually select how large a heap size should be allowed for each app. In CM, for example, this option appears under "CyanogenMod settings" / "Performance" / "VM heap size".

NOTE: BE AWARE THAT SETTING THIS VALUE MANUALLY CAN MESS UP YOUR SYSTEM, ESPECIALLY if you select a smaller value than is normal for your device.

Here are my test results showing the values returned by maxMemory() and getMemoryClass() for four different devices running CyanogenMod, using two different (manually-set) heap values for each:

  • G1:

    • With VM Heap Size set to 16MB:

      • maxMemory: 16777216
      • getMemoryClass: 16
    • With VM Heap Size set to 24MB:

      • maxMemory: 25165824
      • getMemoryClass: 16
  • Moto Droid:

    • With VM Heap Size set to 24MB:

      • maxMemory: 25165824
      • getMemoryClass: 24
    • With VM Heap Size set to 16MB:

      • maxMemory: 16777216
      • getMemoryClass: 24
  • Nexus One:

    • With VM Heap size set to 32MB:

      • maxMemory: 33554432
      • getMemoryClass: 32
    • With VM Heap size set to 24MB:

      • maxMemory: 25165824
      • getMemoryClass: 32
  • Viewsonic GTab:

    • With VM Heap Size set to 32:

      • maxMemory: 33554432
      • getMemoryClass: 32
    • With VM Heap Size set to 64:

      • maxMemory: 67108864
      • getMemoryClass: 32

In addition to the above, I tested on a Novo7 Paladin tablet running Ice Cream Sandwich.
This was essentially a stock version of ICS, except that I've rooted the tablet through a simple process that does not replace the entire OS, and in particular does not provide an interface that would allow the heap size to be manually adjusted.

For that device, here are the results:

  • Novo7

    • maxMemory: 62914560
    • getMemoryClass: 60

Also (per Kishore in a comment below):

  • HTC One X

    • maxMemory: 67108864
    • getMemoryClass: 64

And (per akauppi's comment):

  • Samsung Galaxy Core Plus

    • maxMemory: (Not specified in comment)
    • getMemoryClass: 48
    • largeMemoryClass: 128

Per a comment from cmcromance:

  • Galaxy S3 (Jelly Bean) large heap

    • maxMemory: 268435456
    • getMemoryClass: 64

And (per tencent's comments):

  • LG Nexus 5 (4.4.3) normal

    • maxMemory: 201326592
    • getMemoryClass: 192
  • LG Nexus 5 (4.4.3) large heap

    • maxMemory: 536870912
    • getMemoryClass: 192
  • Galaxy Nexus (4.3) normal

    • maxMemory: 100663296
    • getMemoryClass: 96
  • Galaxy Nexus (4.3) large heap

    • maxMemory: 268435456
    • getMemoryClass: 96
  • Galaxy S4 Play Store Edition (4.4.2) normal

    • maxMemory: 201326592
    • getMemoryClass: 192
  • Galaxy S4 Play Store Edition (4.4.2) large heap

    • maxMemory: 536870912
    • getMemoryClass: 192

Other Devices

  • Huawei Nexus 6P (6.0.1) normal

    • maxMemory: 201326592
    • getMemoryClass: 192

I haven't tested these two methods using the special android:largeHeap="true" manifest option available since Honeycomb, but thanks to cmcromance and tencent we do have some sample largeHeap values, as reported above.

My expectation (which seems to be supported by the largeHeap numbers above) would be that this option would have an effect similar to setting the heap manually via a rooted OS - i.e., it would raise the value of maxMemory() while leaving getMemoryClass() alone. There is another method, getLargeMemoryClass(), that indicates how much memory is allowable for an app using the largeHeap setting. The documentation for getLargeMemoryClass() states, "most applications should not need this amount of memory, and should instead stay with the getMemoryClass() limit."

If I've guessed correctly, then using that option would have the same benefits (and perils) as would using the space made available by a user who has upped the heap via a rooted OS (i.e., if your app uses the additional memory, it probably will not play as nicely with whatever other apps the user is running at the same time).

Note that the memory class apparently need not be a multiple of 8MB.

We can see from the above that the getMemoryClass() result is unchanging for a given device/OS configuration, while the maxMemory() value changes when the heap is set differently by the user.

My own practical experience is that on the G1 (which has a memory class of 16), if I manually select 24MB as the heap size, I can run without erroring even when my memory usage is allowed to drift up toward 20MB (presumably it could go as high as 24MB, although I haven't tried this). But other similarly large-ish apps may get flushed from memory as a result of my own app's pigginess. And, conversely, my app may get flushed from memory if these other high-maintenance apps are brought to the foreground by the user.

So, you cannot go over the amount of memory specified by maxMemory(). And, you should try to stay within the limits specified by getMemoryClass(). One way to do that, if all else fails, might be to limit functionality for such devices in a way that conserves memory.

Finally, if you do plan to go over the number of megabytes specified in getMemoryClass(), my advice would be to work long and hard on the saving and restoring of your app's state, so that the user's experience is virtually uninterrupted if an onStop() / onResume() cycle occurs.

In my case, for reasons of performance I'm limiting my app to devices running 2.2 and above, and that means that almost all devices running my app will have a memoryClass of 24 or higher. So I can design to occupy up to 20MB of heap and feel pretty confident that my app will play nice with the other apps the user may be running at the same time.

But there will always be a few rooted users who have loaded a 2.2 or above version of Android onto an older device (e.g., a G1). When you encounter such a configuration, ideally, you ought to pare down your memory use, even if maxMemory() is telling you that you can go much higher than the 16MB that getMemoryClass() is telling you that you should be targeting. And if you cannot reliably ensure that your app will live within that budget, then at least make sure that onStop() / onResume() works seamlessly.

getMemoryClass(), as indicated by Diane Hackborn (hackbod) above, is only available back to API level 5 (Android 2.0), and so, as she advises, you can assume that the physical hardware of any device running an earlier version of the OS is designed to optimally support apps occupying a heap space of no more than 16MB.

By contrast, maxMemory(), according to the documentation, is available all the way back to API level 1. maxMemory(), on a pre-2.0 version, will probably return a 16MB value, but I do see that in my (much later) CyanogenMod versions the user can select a heap value as low as 12MB, which would presumably result in a lower heap limit, and so I would suggest that you continue to test the maxMemory() value, even for versions of the OS prior to 2.0. You might even have to refuse to run in the unlikely event that this value is set even lower than 16MB, if you need to have more than maxMemory() indicates is allowed.

Out of Memory Error in android due to Heap Size Increasing

Your question has two parts:

1) How can I determine the size of the heap on my test device?

2) Why is my app exceeding the size of my heap?

Regarding question 1, you can determine the size of the heap on your test device directly in your code by calling:

Runtime.getRuntime().maxMemory();

See this post for additional information on that method, as well as some example heap sizes available on various devices.

Also, if you are running a rooted device, there may be a way to directly set (and check) the heap size via the interface. For example, in CyanogenMod's various versions of Android, from the Settings menu, you can select "CyanogenMod settings," and then "Performance," and then "VM heap size," and directly view (and change) the heap size for your device. Be careful, as setting the heap size too small can make your device misbehave or worse.

Regarding question 2: You have not provided enough information to diagnose your specific problem, and in any case, doing such a diagnosis second-hand is difficult at best. Your best bet for resolving this issue (and for learning something of lasting value in the process) would be to become familiar with some of the very powerful memory analysis tools available in Android (some of which are also integrated into the Eclipse IDE). I use these tools from Eclipse, so that is what I will describe below.

First of all, make sure your Eclipse version is up to date by installing the latest version of Eclipse (e.g., Indigo).

Next, in Eclipse, select Help/Install New Software, and then click the dropdown at the top and select

"Indigo - http://download.eclipse.org/releases/indigo"

Next, open the General Purpose Tools category by clicking the plus sign next to it, and select Memory Analyzer and also Memory Analyzer (Charts) [optional]. Install these tools.

Next, select Window/Preferences, and then Android/DDMS, and select the HPROF action as "Open in Eclipse." This will cause any HPROF heap dump file that you generate from DDMS to be of the appropriate format for Eclipse, and will also cause it to be automatically opened in Eclipse's Memory Analyzer (which was just installed above).

Now, open DDMS by selecting Window/Open Perspective/Other/DDMS. Select the Devices icon (looks like a phone) on the left and drag the resulting window so that it is docked somewhere you can see it easily.

Make sure that your device is connected to the PC via USB, and that your app is running.

In the Devices tab that you have just created, select your running app's process. Run the app to the point where it has occupied enough memory that you know it has leaked, but not so much that it crashes. Now, click the Dump HPROF File icon in the devices tab. After a brief delay, you'll be offered a choice of reports on your heap. Try the Leak Suspects Report to get started. This report will open in the Memory Analysis Tool. It tells you where your app is using memory. Check the various kinds of objects and see if they look bloated relative to the amount of data that you would expect them to require; if so, that may indicate a leak.

Here is a nice tutorial describing in more detail how to generate and explore your heap using DDMS and the Memory Analyzer Tool.

Back in DDMS (or the DDMS perspective in Eclipse), you can select the Allocation Tracker tab while your device is attached, and then your device from the devices tab, and then select your app's process from the list for that device. Then, in the Allocation Tracker tab, click the Start Tracking button, and then run your app's relevant operations (those that you suspect are leaking), and then click the Get Allocations button, and then select the Stop Tracking button.

This will display all allocations that have occurred while you were tracking (there are limits to the amount it will store). Clicking on any one of these will take you to the stack at the time of allocation, and clicking on any part of that stack dump will take you to the source code that was involved in the allocation.

These tools should give you some insight into what might be causing your app to leak memory.

Android devices with small heap

is there a list of android devices and their heap size?

Not that I am aware of.

Could I simply assume that all devices with 512MB Ram have 32M of heap?

Heap size recommendations are driven more by Android OS release and screen size. Android OS release and screen size also have an impact on minimum effective RAM on the device. So the concepts are loosely correlated, but that's it.

I'd like a list so I could determine mainly if Android 2.2+ devices with 16mb heap exist

AFAIK, you cannot rule out that combination. After all, please remember that Android is open source, so modded ROMs are welcome to configure heap sizes however they want. IIRC, at least one allows the user to choose the heap size. And there are no rules regarding device RAM or heap size in the Compatibility Definition Document, so device manufacturers are welcome to try odd combinations.



Related Topics



Leave a reply



Submit