3

I'm writing an image manipulation tool and, for image quality reasons, want to edit the image in as large a size as possible.

I need to be careful that I don't run out of memory while my app is running. In addition, I want to take advantage of devices with lots of memory. For example, I'd like to support medium size images on less powerful devices like the G1 and let more powerful devices like the Samsung Galaxy S support large images.

Is there a reliable way to gauge how much memory my app can use?

My current idea is that, when deciding on the image size to load, the device could calculate the image size that brings memory usage for the app as close to about 70% as possible (i.e. not 100% as you don't want the app crashing on small allocations later or because of memory fragmentation)

I've found I can use the following code to return a percentage of the available memory:

double totalMemoryUsed = (Runtime.getRuntime().totalMemory() + android.os.Debug.getNativeHeapAllocatedSize());
int percentUsed = (int)(totalMemoryUsed / Runtime.getRuntime().maxMemory() * 100);

New bitmaps add to the native heap allocated part. This seems reliable in that my app will predictably crash with an out of memory error when percentUsed goes above 100%. Are there any caveats to the above calculation I need to be aware of?

rbcc
  • 2,452
  • 3
  • 26
  • 28
  • What I would be worried about is everything being okay, and then android unwisely deciding to resume a previously resource-killed background process and causing your application to crash as a result. – Chris Stratton Jan 18 '11 at 17:47
  • Your calculation doesn't make sense to me. IMHO you should use a combination of `Runtime.freeMemory()` and `Runtime.totalMemory()`. If you are using Debug.getNativeHeapAllocatedSize() you may be counting twice, see http://stackoverflow.com/questions/1945142/bitmaps-in-android/1949205#1949205 To clarify Runtime.totalMemory() is the amount available to your program while maxMemory() is the amount available to the VM. – Roland Jun 23 '11 at 18:48

1 Answers1

0

Are there any caveats to the above calculation I need to be aware of?

My first thought is that you really can only rely on the accuracy of a calculation like that at the instant when you perform it. Android has all sorts of services and other applications that are running in the background. At any given instant, the amount of memory currently in use is going to change. There is no way to tell by how much until you perform a calculation again. Additionally, no two phones are going to be alike so you really can't accurately estimate it.

You would almost need a thread or async task recalculating this on a constant basis which I'm not sure is a good idea.

I would stray away from this, and consider building your app using a different strategy. But good luck to you if you continue to pursure it.

user432209
  • 20,007
  • 10
  • 56
  • 75
  • The maximum memory parameter being returned in the maximum memory for the current application however (when your application goes over this, it is killed). For example, on a G1, this is limited to 16Mb per application. This doesn't change no matter what is running in the background. – rbcc Jan 18 '11 at 19:30