Does increasing RAM help to prevent OOM? - android

OOM happens when the heap gets full. But what if we increased the size of the RAM of the device, will that help prevent OOM?
I tried to look at tutorials on how to prevent OOM , which recommended multi-threading and trimming down the size of the bitmap. But I still get OOM errors.

But what if we increased the size of the RAM on the device, will that help prevent OOM?
Yes and no. The answer is "it depends on why you are running out of memory."
If you are trying to manipulate a 2GB Bitmap on a 1GB device, then yes, adding a few extra GB of RAM will solve your problem.
If you have a rogue operation that is constantly allocating new Objects, then adding additional memory will just delay the OOM Exception. Extra RAM is not a long term solution to poor memory management.
You need to work to identify why you are running out of memory first. If the issue is that you really do need more RAM (which is fairly unlikely), then go ahead and add more. If the problem is that you are unnecessarily allocating memory or leaking objects, then fix those problems first.
With Bitmaps specifically, you often don't need the full quality image. If your image is stored at 1080p resolution but the device is only a 480p screen, then loading the entire image into memory is a waste of space since most of the image won't be used anyway.

Related

Lots of RAM use by very large byte arrays?

I have been trying to fix a memory leak in my app for a long time, and I keep running into dead ends. The app is heavily image-centric, so I use the Picasso library to handle caching and memory use. I passed the high ram use (up to 100-170mb for my app) to bad memory management on Picasso's part, but I did some testing and disabled memory caching for Picasso, which loads all my images, and there was not a very noticable drop in RAM usage. It was still using 90 to upwards of 170 mb of RAM. I did a full heap dump into a hprof file and opened it with MemoryAnalyzer to see this:
http://i.gyazo.com/6b8d884852fa7cae546fc4cad1fc44c9.png.
If I go to Path to GC Roots, it shows no roots and no parents. There is no link to any of these over 50,000,000 bytes in these 25 massive byte arrays, and I really don't know where to start looking for the cause of it.
Do you have any suggestions on what the bug could be and any possible fixes?
Thank you very much for helping me out!
Try to use LeakCanary to find the memory leak.
Also, you can try Fresco for image loading & displaying, it stores images in the native memory region, so you won't use too much memory from the managed region, GC won't take too much time and you could avoid OutOfMemoryErrors.

How to know app going to reach max heap memory?

I am making Image gallery app with various types of image in term of resolution and size.
As per my observation, when app try to load large image its throws OutOfMemory.
How can i prevent app from OutofMemory?
Is there any way to get notification before app get crash because of OutOfMemory?
How can i know app going to reach heap capacity?
How can i prevent app from OutofMemory?
Allocate less memory. For example, with images, use things like inSampleSize on BitmapFactory.Options to only load into memory what you need, not the whole image.
Also, if your images will be the same resolution, use inBitmap to reuse already-allocated Bitmap objects, rather than let them get garbage-collected.
Is there any way to get notification before app get crash because of OutOfMemory?
No, because you are not out of memory.
How can i know app going to reach heap capacity?
You are not reaching "heap capacity".
Dalvik's garbage collector is a non-compacting (or non-moving) garbage collector, and so over time your heap becomes fragmented. OutOfMemoryError means that you are trying to allocate something for which there is no single free block big enough. I wrote a blog post that explains this a bit more and explains how the new ART runtime will help in this regard in the future.
getMemoryClass() gives you an estimation of how much memory you have available in your application.
getLargeMemoryClass() gives you an estimation of the large heap size you can allocate to your application.
So debug your application first to know where does it throw an exception exactly (line) then add logs to see how much memory you got.

Maximum Heap size for Nexus?

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.

Difference in garbage collector behavior on Android device versus the emulator

I'm testing my application's memory usage on the emulator. And the problem is that on the emulator the app heap is just growing and growing, just a little bit of resources are freed. And if no collections are made it will cause an OutOfMemory exception on big resolution screens.
I downloaded the Sony SDK and there is an emulator configuration for the Xperia Z that has 1080x1920 resolution and the default heap is 64MB. I think it's a small heap size for that resolution because my app uses 40MB only starting up. However on my phone it's using 15MB of 64MB (res. 540x960).
So this quite small heap size (might not be real?) + GC behavior is causing OutOfMemory quite fast.
On a real device (I've tested only on mine), GC is working very nicely, it's freeing resources that are no longer used, but I really cannot predict if that will work on other phones.
Should I ignore how GC is working on my emulator or might it be my app's problem?
Growing heap on emulator indicates that at some point you have memory leak.
They are very common when you send intents between different applications ( e.g select image from gallery) . Most of device can handle such leaks with no problem.
Another reason for heap to grow up: inefficient memory operations. That means at some time you are asking to much memmory ( e.g you selected 5M image from gallery, created inpuststream for it and keep in memory as bitmap, so you asking 15+M emulator will show just hight heap grow, but most of devices will show error).
If you see heap grows - analyse your memory usage and detect leaks. Link
If you dont detect anything strange you can almost safely ignore heap warning.
Note: heap show supplied space, not used.

Android grow heap frag case

I'm working on an app to streaming music from internet... My app does many things and it's structured in this way: I have a tab view and every view is allocated in memory so every time I navigate through tabs I find again the previous status ( every tab can also open a webview to find information about songs, news etc in internet ).. all that grows memory occupation but makes the app very user friendly... After having paid attention to avoid memory leaks following the Android guide, I tried to look at the heap occupation and I found that my app allocates max 3.5MB of memory and the heap size allocated is 4.5 - 4.6 MB... I'm working on the emulator .. They are not so much I think, but sometimes my app is restarted founding in LogCat a strange message like
Grow heap ( frag case ) to 3.373 for 19764-byte allocation
What is it? an emulator issue? or something else? Am I using too much memory?
Thank you in advance for any help :)
The maximum heap size depends on the device (you can get that value by calling Runtime.getRuntime().maxMemory()), but it's probably around 32MB. In order to save memory, Android doesn't allocate maximum memory to every app automatically. Instead it waits until the app need more memory and then gives it more heap space as needed until it's reached the max. I believe that's the Grow heap message you see.
If you do a lot of memory allocation and freeing, you may run into fragmentation problems. Wikipedia has a decent description here, but basically means that you might have the required memory available, just not all in one chunk. Hence the need to grow the heap.
So to answer your questions, it's probably not an emulator issue, it's just the nature of your program, which sounds a little memory heavy. However this isn't a bad thing. I don't think using 3-5MB for multiple tabs with webviews is too much.

Categories

Resources