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.
Related
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..).
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 )
hi i am new to android and i have come across some memory management issues whilst using xml to position and design my activity layouts.
most images are around 100kb but vary in size e.g. image 1 will be 512x512, image 2 will be 120x320 etc.
at the moment the images are slowing down my app's performance and sometimes crashing.
Is there a way to reduce the amount of memory an image takes up on an app?
There's a number of steps that applications must go through in order to handle bitmaps sanely.
Small Compressed Size. It's important to balance quality vs. file size for your on-disk (or on-wire) formats. Being able to run PNG files through a lossy pre-processor, or choosing to use WEBP/JPG where needed are critical for each image in your app. Smaller PNG Files covers this more. The problem here, however, is that this doesn't help you with in memory size. Remember when your images are loaded from disk, they are decompressed into 32 bits-per-pixel in memory (in other words, no compression).
Compressed In Memory Format. Android provides the alternate 565 format, which uses only 16 bits per pixel, instead of the 32 bits for the 8888 format. If you're using an image that doesn't need alpha, you should consider the process discussed in Smaller Pixel Formats to leverage loading a bitmap as a 565.
Re-Using bitmap space. Most applicaitons that use thumbnails, only really have 10-20 of them visible on screen at one time (even though there may be thousands to load). The trick here is described in Re-using bitmaps. Basically, once a thumbnail is no longer needed, you can re-use it's space for an incoming thumbnail, rather than allocating a brand new one.
Display resolution. It makes no sense to load a 2MB image, to only display it as a thumbnail. Instead, you should be scaling the image to the resolution of what it'll display at, on the device. I discuss the most efficient way to load these images in the other SO post.
In general, Libraries like Picasso and Glide do a good job at providing APIs that make all this easier; but they are still going through these same processes under the hood.
You have 3 solutions you can do:
1st Solution:
Add in your AppManifest.xml in your application tag:
android:largeHeap="true"
This will try to prevent your app from causing OutOfMemoryError, but use it with caution.
Documentation: Whether your application's processes should be created with a large Dalvik heap. This applies to all processes created for the application. It only applies to the first application loaded into a process; if you're using a shared user ID to allow multiple applications to use a process, they all must use this option consistently or they will have unpredictable results.
Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.
2nd Solution:
If your images' file size are large, you can minimize them by using this online tool: http://compresspng.com/
3rd Solution:
You can use BitmapFactory for loading your images. Here is the Android Developers documentation: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
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
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.