Android RAM usage and how to decrease it? - android

I have been coding this application that shows images of bus lines schedules. There are currently 32 lines and each of them has it's own image (can't use text due to the formatting and lack of data, had to do a compromise). I made it fetch an echo from a PHP file on my server and it retrieves data regarding bus lines and their images, then it downloads that data and images to the internal storage and loads the buttons for each line (dynamic layout).
ImageViews are set to null when they are created and they are only populated once you click on the button. I have noticed that my app uses around 20MB of RAM just as it starts. Opening 10-15 lines (10-15 images are loaded into ImageViews), RAM usage climbs up to 60MB and then it crashes (reaches my device's heap size limit). I know that image intensive applications tend to use a lot of RAM and my plan is to limit it to only one image per time (so once the user clicks on some other bus line, the others are closed and their imageviews are set back to null), but what is wondering me, can empty ImageViews cause RAM to be around 20MBs? My images are 320px in width and ranging from 200 to 1500px in height (I know, it's a lot), but I have set them to grayscale and compressed them (Size of the images is from 50kb up to 150kb).
My application's APK is 710kb in size, app when installed is around 3MB and with data it totals to 7.5MB.
So, to clarify, my questions are:
*1) Can empty ImageViews cause high RAM usage as well?
2) If yes, should I dynamically create an ImageView and populate it once the user clicks on the button, instead of the current approach when they are all created at startup?
3) Can multidimensional variables (mostly strings, 6 strings with 35 dimensions) cause high RAM usage as well? Most of them are around 10 characters long.
4) Are there any tools which I could use on Android Studio which could help me to locate possible memory leaks?
5) Do non-global variables get automatically destroyed once the ie. function has returned a value or do I need to manually set them to null after I'm done with them?
6) What are generally some good practices to reduce RAM usage on Android when developing an app?*
Sorry for not being very technical here, I'm not a professional programmer or anything, this is more of a hobby of mine and I'm trying to learn a bit more here. Thank you for reading.
Image that shows what my app does:
All bus lines are collapsed
Once you click on the button, it shows the bus schedule for that line

*1) Can empty ImageViews cause high RAM usage as well?
Probably not. It's the bitmaps themselves that take a lot of space, not the ImageViews. Keep in mind that in-memory bitmaps won't be compressed, so it's not the file size that you need to take into account but the number of pixels.
3) Can multidimensional variables (mostly strings, 6 strings with 35
dimensions) cause high RAM usage as well? Most of them are around 10
characters long.
Probably not.
4) Are there any tools which I could use on Android Studio which could
help me to locate possible memory leaks?
You should use the Android Debug Monitor (Tools menu > Android > Monitor (DDMS included). It has a memory heap viewer that will show you what the big offenders are. It can take heap dumps in HPROF format that you can also analyze with other Java heap viewing tools.
5) Do non-global variables get automatically destroyed once the ie.
function has returned a value or do I need to manually set them to
null after I'm done with them?
Unless you're doing something strange, the memory used by local variables is eligible for garbage collection once those variables pass out of scope, so to answer your question, you don't need to set them to null.

In my case, I only put the 1 image to drawable so the RAM of application increase a lot.
Then, I put image to each drawable-...pdi files, the RAM size decrease

Related

How to view bitmaps taken from memory dumps?

Background
android apps usually have a low amount of heap memory for them. that's why you always need to avoid holding large objects.
since the app i'm working on can get OOM on some cases, i thought that i should check out what causes the memory to be low.
i've used MAT plugin and i've found out that the app has 3 bitmaps that take 3.5MB each.
The problem
the app already has multiple bitmaps being used, but they are way smaller (less than 1MB each).
in fact i've even put breakpoints to make sure each bitmap i create don't take so much memory, and found nothing.
i've also watched some google IO videos (like this one) regarding this matter. it seems that in order to see which class has a reference to the object, you click on the object and choose "Path to GC roots"=>"exclude weak references".
What I've tried
you can see in the dominator-tree which bitmaps take the most (look at "retained heap").
in order to export the data, you can choose the byte array and then "copy"=>"save value to file".
however, like others have tried on this post , i'm stuck at showing the bitmap itself (need to know its format, width and height). plus it could be quite annoying to use GIMP for this task.
The question
how can i view the bitmaps (the image itself) within eclipse?

Android Fatal Signal 11 from XML

I am creating an Android app and I have yet to run out of memory until just now. The part that is confusing is it was not a way I would expect to run out of memory.
I simply added a new Linear Layout to a layout xml file. It had a background of an image that was 40kb large. The other images that were loaded were approximately 12kb with the background being much larger at 120kb. When this image was loaded I would receive a Fatal Signal 11 on runtime. If I removed the background from the layout it would work fine. I then changed the image to be much smaller, it was (2000x600) before so now it is 14kb. It now works fine. It is clear that the extra 26kb was causing a problem...
What kind of precautions should I take to ensure this doesn't happen again. Obviously I would like quality images and the 2000x600 might be excessive as it's an app for a phone but what guidelines should I follow?
Is there a memory usage cap that can be extended or that I should look to stay under? Also, if I loaded many images on a scrollview will this cause the app to crash? I have had many images loaded at once but have never had it crash before, I'm just confused as to the error being caused by very little memory usage. (In todays terms at least.)
Regards,
Jake
Images do not consume the same amount of memory in RAM as they do on disk. You can get the RAM usage by:
width*height*4 (for images with an alpha channel)
and
width*height*3 (for images without an alpha channel)
An Android app is allotted a definite amount of heap space in the RAM, which will always be the same on a particular device and ROM version on that device. The minimum is 16 MB, though these days most devices give you a more comfortable 32 MB or 64 MB. It really depends on the device.
You get Out of Memory Exceptions (OOMs) when your app exceeds this heap space. The simple fix is: Don't exceed this heap space.
The best way to get quality images in your app is to use the density buckets and provide different sizes from which Android can choose. LDPI screens cannot make use of high res images anyways, so you should only supply a low res on in LDPI. On the other hand, HDPI devices can make use of better resolution, and if you supply one Android can use it. It is almost a given that the higher the resolution of the device, the more heap space you will be allotted for the running of your app.
Another way to manage memory is to only load what you need, by implementing lazy loading. This is especially helpful with listviews and scrollviews and other adapter based View systems.
On Android 3.0 and above, you can request a bigger heap by using android:largeHeap="true". However, this should be avoided as the user will notice other apps of theirs being removed from memory whenever your app is launched, and it is not guaranteed that you will receive a larger heap in any case.

Android java.lang.Outofmemorry+imports

I would like ask you simple question.
I fight with java.lang.outofmemory error. I
t is caused probably by pictures but also I have in my project quite alot unused imports and unused variables at this moment (application with 7 activities and every activity aprox 40 variables).
Take unused imports and unused declared variables memory ?
Do you think, can be java.lang.outofmemory error caused of many variables and imports ?
From Android:
Bitmaps take up a lot of memory, especially for rich images like
photographs. For example, the camera on the Galaxy Nexus takes photos
up to 2592x1936 pixels (5 megapixels). If the bitmap configuration
used is ARGB_8888 (the default from the Android 2.3 onward) then
loading this image into memory takes about 19MB of memory (2592*1936*4
bytes), immediately exhausting the per-app limit on some devices.
Basically, Images are a killer if not used properly.
See this android tutorial on Loading Large Bitmaps Efficiently
Specifically, the code examples to loading in scaled bitmaps from files/resources, at the required resolution.
Imports have no effect on the memory, at run time. The only thing they might do is slow down the build time. Nothing detrimental.
No, variables not occupy more memory in Heap of application. This may be due to bitmap in your application. If you are getting any error, make sure you have released images background like
imageview.setBackgroundDrawable(null);
relativeLayout.setBackgroundDrawable(null);
or
imageview.setBitmapImage(null);
This will remove drawable images used in layouts.

Android. How to keep cache in RAM?

I need to search through text files (around 40MB) in my app with regular expressions, as you can imagine, it normally takes 1 minute or so to get it done. AND I have to do it repeatedly.
I wonder if I can keep these files in RAM after the first search. Can I possibly do that? I mean, find a way to explicitly say keep something in RAM for some time.
Consider putting your search results in a WeakHashMap, with keys that only exist for the duration that you need the values to exist, like the scope of an Activity. Watch out for memory issues though. On some devices, your application's process may only have a heap size as low as 16M.
Keep the results in a custom object that will save the search result. This will keep it in RAM (as long as you keep a reference to it).
Also keep in mind that allocating 40 MiB in RAM in Android devices is not a very good idea since RAM is quite limited in a lot of low-end devices. This can make your application a very tasty target for Android when it looks to free memory.

Android VM heap strategies for big images

I am manipulating relative large images, about 5MP and sometimes even more. I need two copies of the images in memory for manipulation.
Now, the loaded images consume a lot of memory, more than available by the default Android heap which is 16MB respectively 24MB which results in the following error:
11-20 18:02:28.984: E/AndroidRuntime(7334):
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
I need full resolution, thus downscaling while loading the images does not help.
What's the best solution to get over this problem? Are there built-in methods to dynamically load only chunks of bitmaps from storage? And can someone give me some hints how I can overcome the memory problem, e.g. by using specific caching strategies?
Regards,
You can allocate more memory in the ndk. You'd have to write native code to manipulate the images, or you'd have to figure out a way to allocate the image memory in native, then pass it back to Java.
Bitmap/Canvas use and the NDK
Another option might be to load a single image into memory, and break it up into chunks for processing. Save those chunks out to the file system. So, say you 2 large images. You load the first image, break it into 4 parts, save them, load the second, break it into 4 parts, save those, then load part #1 for each image, and do your thing. That implies you know that neither individual image is larger than the heap max, and that what you need to do is (basically) pixel level and doesn't need access to surrounding pixel data (you'll run into trouble at the edges if you need neighbor pixel info).
Without downsampling, splitting, or ndk, I don't know how you'd get more image data into memory. Perhaps lowering the color info. We do this in a product. Represent each pixel as 16 bits rather than 24 or 32. Our product is functional rather than "pretty", so the loss of color info wasn't a big deal.
You should watch this video on memory management: http://www.youtube.com/watch?v=_CruQY55HOk
At about 6 mins into it he covers the LargeHeap manifest option added to HoneyComb.

Categories

Resources