128

I am writing an Android application which uses several 3D models. Such a model with textures can take up a lot of memory. I found out the manufacturer sets a limit on the heap size an application can use. For example my tablet Samsung Galaxy Tab 8.9 P7310 can take up 64MB of memory.

Is there a way to increase this size of memory an application can use?

cooxie
  • 2,624
  • 4
  • 16
  • 17

7 Answers7

212

You can use android:largeHeap="true" to request a larger heap size, but this will not work on any pre Honeycomb devices. On pre 2.3 devices, you can use the VMRuntime class, but this will not work on Gingerbread and above.

The only way to have as large a limit as possible is to do memory intensive tasks via the NDK, as the NDK does not impose memory limits like the SDK.

Alternatively, you could only load the part of the model that is currently in view, and load the rest as you need it, while removing the unused parts from memory. However, this may not be possible, depending on your app.

Raghav Sood
  • 79,170
  • 20
  • 177
  • 186
  • NDK looks interesting. Could I use it in combination with my code already written with SDK? – cooxie Jun 30 '12 at 17:08
  • 3
    That depends completely on what code you have. I'm not an expert with the NDK, and know only the basics. I would recommend you ask this question along with a description of your code on the android-ndk Google group, or post a new question on SO specific to this with the android-ndk tag. – Raghav Sood Jun 30 '12 at 17:13
  • I wonder if we can't "simply" use Unity3D as a more specific answer to the question ("uses several 3D models")... Couldn't quickly find any clear evidence on whether unity does use NDK. – cregox Nov 12 '15 at 12:11
  • 4
    `largeHeap=true` FTW – Luis Artola Oct 31 '16 at 19:39
  • 2
    the developers of android api are really funny , they are like you want more Heap ? Ok request it , it's only for those who need it... meanwhile every developer is adding it as first thing to add when the app comes to production :) – AndroidLover Feb 28 '17 at 16:27
  • 1
    @cregox Unity can build to C++ if we choose build type is `Il2CPP` in `PlayerSettings` [link](https://docs.unity3d.com/Manual/IL2CPP.html) so I think if we want to do any heavy things that need a good performance then we can build it by Unity, export to a module and import that module to Android – DungPhan Oct 27 '20 at 09:14
  • 1
    @dung thanks for the update! by now i got a much better and completely out of this whole box "solution" (at least for myself), but you'll think it's just literally crazy disconnected offtopic if i tell you only the 1 word... instead i'll just say that i don't code for over 5 years and have no computer for over 1 year, and i could never be as happy or accomplished as i am today if i continued on this path. cheers! – cregox Oct 27 '20 at 13:23
  • 1
    @cregox I don't know what do you do but I'm sure that you are getting happiness with your current path. Thanks for the response and wish you always happiness and success on your way! – DungPhan Oct 28 '20 at 11:39
111

Is there a way to increase this size of memory an application can use?

Applications running on API Level 11+ can have android:largeHeap="true" on the <application> element in the manifest to request a larger-than-normal heap size, and getLargeMemoryClass() on ActivityManager will tell you how big that heap is. However:

  1. This only works on API Level 11+ (i.e., Honeycomb and beyond)

  2. There is no guarantee how large the large heap will be

  3. The user will perceive your large-heap request, because it will force their other apps out of RAM terminate other apps' processes to free up system RAM for use by your large heap

  4. Because of #3, and the fact that I expect that android:largeHeap will be abused, support for this may be abandoned in the future, or the user may be warned about this at install time (e.g., you will need to request a special permission for it)

  5. Presently, this feature is lightly documented

CommonsWare
  • 910,778
  • 176
  • 2,215
  • 2,253
  • @CommonsWare if having a largeHeap is not available, how can I remove previously loaded objects (like images) ? – Jeongbebs Nov 11 '13 at 07:19
  • @MiguelRivera: For images, ideally you recycle their memory (see `inBitmap` on `BitmapOptions`). Beyond that, remove all references to them, and *eventually* they will get garbage-collected. – CommonsWare Nov 11 '13 at 12:26
  • and what decision you suggest ? – Gennadiy Ryabkin Mar 12 '14 at 10:49
  • @zest: I do not know what you are referring to, sorry. – CommonsWare Mar 12 '14 at 10:52
  • I think #3 is not true. Every application has its own heap. If there is not enough memory (for a specific app) then the OS will kill other apps, so it can utilize the whole heap no matter what happens. – kupsef May 21 '14 at 08:41
  • @kupsef: The app certainly can use its large heap. Point #3 says that the user is going to notice this. – CommonsWare May 21 '14 at 11:39
  • Yeah but this won't cause other apps to run out of RAM. They will have the full heap to use, no matter what other apps do. – kupsef May 21 '14 at 13:27
  • @kupsef: By "force other apps out of RAM", I mean "terminate other apps' processes to free up system RAM for use by your large heap". – CommonsWare May 21 '14 at 13:29
  • so wait... if I request a large heap, but don't wind up needing it, does the memory still get needlessly allocated to my application? – Michael Dec 30 '14 at 04:11
  • @Michael: No. `android:largeHeap` sets the maximum heap that you can allocate to a higher level. It does not pre-allocate that heap space. – CommonsWare Dec 30 '14 at 11:59
  • Does using `large heap` cause decrease in performance? In gallery apps for example. – Eftekhari Apr 26 '16 at 17:18
  • 2
    @Eftekhari: Not directly, for your app. Having more stuff may cause you to spend more CPU time going through that stuff, but the details there would depend on what you are doing with the memory and is not directly tied to having requested `android:largeHeap`. However, requesting a large heap may harm the user experience overall, by forcing other application processes to terminate earlier than would have been needed otherwise. – CommonsWare Apr 26 '16 at 17:22
23

you can't increase the heap size dynamically.

you can request to use more by using android:largeHeap="true" in the manifest.

also, you can use native memory (NDK & JNI) , so you actually bypass the heap size limitation.

here are some posts i've made about it:

and here's a library i've made for it:

Community
  • 1
  • 1
android developer
  • 106,412
  • 122
  • 641
  • 1,128
  • @ per app does heap limit at java level and native is different? i.e example on s5 devcie 128mb java heap limit and native can take another128 mb? – NitZRobotKoder Dec 11 '17 at 16:01
  • Heap size is constant for each app (size depends on hardware and rom) and should be the same for all. The native memory is the real one of the device, but it's of course limited too, as some of it is used by the OS. – android developer Dec 12 '17 at 07:34
  • i meant if my app is using say native .so+ java android Platform + java POJO logic + JavaScript. Does android has different heap size at each level? – NitZRobotKoder Dec 12 '17 at 08:29
  • https://stackoverflow.com/questions/47714637/android-profiler-vs-java-api-level-memory-calculation – NitZRobotKoder Dec 12 '17 at 08:30
  • @NitZRobotKoder No. The heap size is for the Java/Kotlin world, where you can get OOM exception if you use too much. For the rest, it's the native memory. – android developer Dec 12 '17 at 08:36
7

Use second process. Declare at AndroidManifest new Service with

android:process=":second"

Exchange between first and second process over BroadcastReceiver

Yura Shinkarev
  • 4,684
  • 6
  • 29
  • 51
5

This can be done by two ways according to your Android OS.

  1. You can use android:largeHeap="true" in application tag of Android manifest to request a larger heap size, but this will not work on any pre Honeycomb devices.
  2. On pre 2.3 devices, you can use the VMRuntime class, but this will not work on Gingerbread and above See below how to do it.
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

Before Setting HeapSize make sure that you have entered the appropriate size which will not affect other application or OS functionality. Before settings just check how much size your app takes & then set the size just to fulfill your job. Dont use so much of memory otherwise other apps might affect.

Reference: http://dwij.co.in/increase-heap-size-of-android-application

Web Developer in Pune
  • 1,684
  • 16
  • 19
3

From what I remember you could use VMRuntime class in early Android versions but now you just can't anymore.

I don't think letting the developer choose the heap size in a mobile environment can be considered so safe though. I think it's easier that you can find a way to modify the heap size in a specific device (not on the programming side) that by trying to modify it from the application itself.

Jack
  • 125,196
  • 27
  • 216
  • 324
0

Increasing Java Heap unfairly eats deficit mobile resurces. Sometimes it is sufficient to just wait for garbage collector and then resume your operations after heap space is reduced. Use this static method then.

Zon
  • 12,838
  • 4
  • 69
  • 82