Strange Bitmap using 1 Mb of Heap - android

Out of curiosity, I just recently tested my Android App for Memory Leaks, using the Eclipse Memory Analyzer.
I came across a strange Bitmap with the size of 512 x 512 pixels using up about 1 Megabyte of my devices heap memory.
I checked my drawables folder and could not find a bitmap of that size (512 x 512).
I started googling and came across this question, where a user explains how to get the actual Image behind a "memory leak" reference in the Memory Analyzer:
MAT (Eclipse Memory Analyzer) - how to view bitmaps from memory dump
I followed the tutorial and with the help of GIMP, I extracted the following Image:
So my questions are:
What is that?
What is it doing in my applications heap?
How do I get rid of it?
Does anyone else have the same bitmap in his heap?
Notes:
In my drawables folder is no Bitmap looking like that
The largest Bitmap my app uses is 140 x 140 pixels
I have a feeling that this Bitmap somehow comes from the system
The Bitmap is in heap right after app start - without any user interaction
I am debugging on a HTC One S, Android 4.1 Cyanogen Mod (Screen 540 x 960)
I am not using external Libraries
Update:
With the help of Selvin's suggestion and my personal felling that this could be a System-issue, I tested two other apps of mine.
Both of the apps I tested also showed the same Bitmap in the Memory Analyzer with exactly the same amount of bytes consumed:
Furthermore, I was able to find out that:
The source of the Bitmap is always associated with the LAUNCHER Activity of the app.
So what to do about that?
Is there a way to get rid of it?
Since I do memory-intensive operations in my app, I'd like to have as much heap available as possible.

The default window background used by Android is a 512x512 image (the blueish-dark gradient you see with the dark theme or the gray-white gradient with the light theme). On capable devices, this image is replaced with a procedural gradient as of Android 4.2.
Note that this bitmap is normally loaded in Zygote and shared by all the apps. It might show up in heap dumps if the dump doesn't exclude Zygote-allocated objects.
Here are the two 512x512 backgrounds I'm talking about if you're interested:
https://github.com/android/platform_frameworks_base/blob/jb-mr0-release/core/res/res/drawable-nodpi/background_holo_dark.png
https://github.com/android/platform_frameworks_base/blob/jb-mr0-release/core/res/res/drawable-nodpi/background_holo_light.png

Related

Android UI images memory issue

I'm building an application with very big sized images.
Almost all of my UI components are made of ImageViews.
I only have to show 12 images(ui components) on my first activity, but it consumes 80mb on startup.
The images are divided into each drawable directories using Android Drawable Importer.
By doing this I was able to reduce the runtime memory(which I can see on the Android studio's device monitor) to half, but it is still consuming 80~120mb of memories, which I believe is too much.
The first question is, isn't 80~120mb too much for a four screen(two activities, three fragments) application?
The second is, if it's too much then, what and how can I do to reduce memory usage?
When working with images keep in mind that there is a HUGE difference between compressed format (jpg, png..) and Bitmap. Computing the size of a Bitmap is pretty easy, it's width * height * 4 bytes (assuming that the bitmap has the default configuration argb888). So a full hd image that compressed is xy kb, when decompressed will occupy 8294400 bytes (~8mb). So my advice to reduce memory consumption is... scale down your images. You're asking if 80-120 mb is too much, well it seems like a lot but it really depends on what you're doing. What happen if you force garbage collection (there should be an icon in the device monitor)?Another thing to take into account is how to decompress the images, refer to this and use a library (Picasso, Glide..).

High Memory usage in Android Application (50MB)

I am developing a small tamagotchi for a school project and I have huge problems with the amount of memory the app is using. At first I had 200MB allocated to the app and after a bit of researching I got a easy fix to reduce it to 50MB by renaming the drawable folder into drawable-nodpi. But this is still way to much. While investigating the problem I'm sure that it has something to do with my Layout and UI-Elements because i deleted all my Code and launched my app only with the Layout and the memory usage didn't drop at all.
Here you can see my Layout:
The image-sizes are in average about 30kb and if I calculate the maximum size of possible images in the memory I have around 1.5MB.
So where does all the memory come from? How is that even possible?
If you want to see the app by yourself you can get the project from github:
https://github.com/kruben95/TamaStudent
I would be happy if someone can help me or give me some tips.
I downloaded your project, and here is some suggestions:
1) images are big resolution even if on disk they take 30-40 kb - in memory they are bitmap and bitmap takes a lot of memory, for example body part - 1200x1980 pixels with 4 bytes per pixel this is 9,5 megabytes in memory!!?? now after this bitmap got it must also scale it - this is additional memory, and as you see you have more then 10 megabytes per only one image!! this is extremely HIGH.
2) make images lower resolution. no need to display them so high res.
3) remove from images invisible parts - as i see very big parts are clear
but it takes memory!
4) try to make some images programmatically, like circles etc.
5) in code - don't use alpha for view if you only need to do background, set this alpha directly in color: #00FFFFFF - here is white color with alpha 0. If u use alpha on view it will take additional memory for redrawing (lower performance).
6) google internet for your related topics with tag Best practices and you will find a lot of useful information )

Android how to analyze memory

I'm working with Android on eclipse and while testing the code, I seemed to notice the heap raising to 44MB. I'm searching for the variable that I'm keeping alive and I can't seem to find it for a few days. While looking in the heap (DDMS -> Heap) I get the following:
I tried clicking the "Dump HPROF file" as showed in here, but I don't get the save file dialog and I can't analysis it.
so I'm trying to override it untill I get a new computer..
I'm running Android eclipse on Windows 7.
EDIT:
The problem was the ImageViews I keep; I have two images that I set resource via the code with an image of 0.5MB. My question is: is it possible to add ImageViews without growing the heap by that much? and how come 2 images of 0.5MB cause 40MB grow heap?
To answer your edited-in question, your "0.5MB" images are probably compressed. Jpeg or PNG, most likely.
That doesn't matter once they get decoded. What matters then are the dimensions of the image and the bitmap format being used. A typical bitmap in Android is ARGB_8888, which is 32 bits(4 bytes) per pixel.
That means for every pixel(w*h), it costs 4 bytes of space. Looking at the max size(~15MB), It looks like your image is probably about 1600x1200, or around 2MP.
That's 1600 * 1200 * 4 = 15360000, or ~15MB for each image.
For most things, you shouldn't need an image that large on a mobile device. I don't know your application, but if you don't need it that large, you should look into Loading Large Bitmaps Efficiently.

Why are all my bitmaps upsampled 200%?

I'm having severe memory issues in my application [1]. In order to investigate this, I took heapdumps of my app at different states. I saw that some bitmaps were taking huge amounts of memory. I wrote a small tool [2] that decodes the byte arrays to Windows bitmap files (.bmp), so that I can see the bitmaps and compare them to the files I have in my res/drawable folder.
What I discovered is that all my files are upsampled twice.
I first checked with the biggest one had: a byte array buffer of more than 9MB in the heap, which was decoded to be a nice 1920x1280 picture, while the original one was a 960x640 png file.
I tried with the second biggest, over 3MB, which once decoded showed a nice 754x1200 picture, the original size was... guess what? A nice 377x600 jpg file.
What gives?
I have enabled HW acceleration in my Android Manifest file (though I'm not sure I really need it, I'm just using some basic views and activities).
I'm running stock Android 4.0.2 on a GSM Galaxy Nexus (yakju). I'm receiving feedback from my testers that the issue is present on their 4.0.3 Nexus S, though I couldn't check their heap dumps yet.
I'm trying to save memory here, if Android doubles everything, no wonder the app crashes quickly because the heap usage gets too high (around 64MB in my case). I hope there's a reason and a way around it.
References:
OutOfMemoryError when loading activities
How to actually see a Bitmap taken from an Android heap dump
When you put images in res/drawable, Android will assume they have a dpi of 160, i.e. it is the same as putting them in res/drawable-mdpi. Galaxy Nexus is an xhdpi device, i.e. it has a (generalized) dpi of 320. To compensate for the high resolution display, Android will upsample the images with 200%.
The solution is simple, just put the images in res/drawable-xhdpi instead. Then the declared dpi of the images will match the display you run on, and Android will not perform any scaling of the images.
Please refer to http://developer.android.com/guide/practices/screens_support.html for more info.

Display bitmap of any size in Android

I want to display a bitmap read from the SD card at actual pixel size in Android.
I can't assume anything about the bitmap, other than Android supports its image format. The bitmap might be huge.
Seems simple enough, but when you factor Android memory limitations it gets much more complicated.
Any ideas?
Edit: Attempting to load a large bitmap gives an out of memory error because Android is not able to allocate enough memory to decode it. You can load a scaled down version of the bitmap, but this is not useful to show the bitmap at actual pixel size. The question is about how to show a large bitmap on Android while staying within the app's memory constraints (most likely by loading it in chunks).
Edit 2: The bitmap might be huge, but within the realm of reasonable. I'm talking about user images, not HD Nasa pictures.
The managed code (Java) has memory limits of 16/24/32MB even if your device has a lot more free memory. I'm currently working on an application which needs to do this and the solution is to allocate the bitmap in native code (NDK) and then render views of the image into a Java-allocated bitmap which is the size of the display. In native code you can allocate all available memory of the device, but for some reason the virtual machine limits it.
Since android 2.3 (Gingerbread, API Level 10), you can use the BitmapRegionDecoder. I don't know any solution for older android versions. (and I've been looking for it for my EmailAlbum app)

Categories

Resources