My application use a little memory, it's about 3.4MB, in some old android devices such as GT-I9001. But when i running it in HTC one, my application use very more memory.
Look, the allocated memory is 26.881MB, it's too big, and the free memory only have 2.940MB. Then i use MAT tool check the memory leak, i find the resource bitmap use mach memory.
I can't explain the reason. My application often out of memory. I think Maybe the problem is caused by high screen resolution. If someone also encountered this problem, please join the discussion, thanks!
I debuged the problem, and found some reason:
The onCreate() function in my start activity, and you can see the breakpoint. The application only use allocated memory 3.4MB before calling the setContentView(R.layout.welcome) to load layout xml. Then the application run to next step, it use allocated memory 19MB. So i think this problem must be caused by loading the layout xml.
I modifed the "welcome.xml" file, deleted all widgets, that only have a "RelativeLayout"
But the program also use 19MB memory. Finally, i deleted the backgroud of RelativeLayout and the program memory return to normal size, it only use 3MB.
The size of pictrue "loading_background.png" is only 21KB, i think that perhaps the high screen resolution of high-end device changed the picture size in memory, i will try to use 9.png picture. If you understand this part of the problem, please join the discussion, thanks!
It's not a memory leak if you use big image for background.
File size doesn't matter. When it is loaded into memory it takes width * height of the image * 4bytes.
Use small 9-patch images or shape drawables when possible.
This problem can be solved using drawable-nodpi, look this:
Android background image memory usage
Just try to make a bitmap from 3MB PNG file. You will get a 20MB picture. That's why it's beter to convert your images from PNG to JPG. The quality is not so much different actually, but you will profit a lot from memory side.
just add high resolution images to the xxhdpi folder in drawable. this prevent android scale up the image to the ultra sizes
Related
I am using itemTouchHelper to remove a cardView from a RecyclerView on swipe
my cardview is simple it just has a text and an image
but when i swipe to remove the card disappears but is never taken out of memory (i am saying this because the memory of the image never goes away and it causes an out of memory exception)
my code is very simple so i was wondering if there was a step i was messing that tells the recycler view to remove from memory?
my code is exactly like this one
Usually, images are loaded in android memory, scaled according to device screen resolution requirements, and kept there till the process dies or, is killed or, is collected by garbage collector.
It is possible that your image size in card view (or other images in your res folder) is/are large, and images after scaling by android is occupying too much of memory, to cause memory exception. Try reducing size of your image (Try compare size with the icon sizes that google icons has, they all are less than a Kb, amazing !).
If the above does not work, then create a drawable-nodpi folder in your res folder and put large size images in this folder, this will indicate android to not to scale these images and render it as it is. (make sure you test in all screen devices after following this approach, because now the image won't scale in different screen sizes).
Finally, if none of the above helps try running : System.gc() after there is a card swipe action performed by user. This will run garbage collector and your image will be removed from memory. (This approach does not guarantee garbage collector working in all devices, so make sure that you try for above two approaches, they should work).
Hope this helps !
Sorry for putting a obvious question (?) but it is troubling me for sometime. I am using Glide for image loading and find it quite well in memory management. Now I am thinking to move to Vector drawables with the help of MrVector. Do i really need to worry about the memory management?
For further info, each of my image in JPG of size 200KB-300KB will be become just 20- 30 KB in vector drawables. If this info helps in answering the question. Thanks
Yes.
We had some PNG images that were only about 20kb but because we stretched them to the size of the screen, and Android converts them to bitmap in memory, they were more like 50MB!
Switching to vectors saved all of this memory.
I'm trying to detect my memory leaks.
After watching the video from Google and reading on StackOverflow, I'm starting to give it up because I don't find the issue.
My first Activity loads 4 images from resources (ImageView, for each one the width in pixels are not bigger than 400px), and I can find this on MAT (MainActivity):
then if I start the HomeActivity, this has more imageviews but all of them are short and small. So I load it and I get this:
but if I use regex with HomeActivity or MainActivity:
And this, are supposed to be my LEAKS:
I tried to not to set some images, delete an horizontalScrollView, deleting some items which could be a problem.
And I'm totally lost. Would you know what I'm doing bad?
Thanks in advance.
My first Activity loads 4 images from resources (ImageView, for each one the width in pixels are not bigger than 400px)
First, an ImageView is not a resource. It is a widget.
Second, the size of the ImageView is irrelevant by default when it comes to loading resources.
and I can find this on MAT
You are consuming ~26MB worth of heap for byte[]. If you expand that node in the tree you should see specific instances of this. If you find one of interest, right-click on it and examine its GC roots to try to identify what it is.
So I load it and I get this
This shows two specific byte[] at ~12MB and ~11MB each. Right-click on them and explore their paths to GC roots to try to identify what it is.
Would you know what I'm doing bad?
Not specifically. After all, we do not have any Java code, any resource XML, or anything much to go on.
If I had to guess, you added some large image files as drawable resources and are relying upon ImageView to scale them down to smaller sizes. That's fine, but ImageView does not reduce the heap used by the images themselves. That will be determined by the resolution of the image (width * height) and the bit depth of the image (usually 4 bytes per pixel for ARGB_8888). Resources are never released once loaded, compounding your problem. You can:
Scale the image yourself at compile time to something closer to what you will actually need at runtime, and/or
Use BitmapFactory and decodeResource(), with an appropriate BitmapFactory.Options instance and inSampleSize value, to load the image in more manually, downsampling it at runtime to consume less heap space, and loading it as a regular Bitmap (AFAIK, decodeResource() does not load the resource as an actual resource, allowing it to be better managed at runtime)
I recently added three small images to my apps GUI. They are around 40kb in size. Everything is fine until the screen locks on the device. When I unlock I get this error:
OutOfMemoryError: bitmap size exceeds VM budget
I've seen plenty of articles relating to the error but all seems to be for a different reason. I'm not doing anything fancy like downloading from the internet. Just local resources for the UI.
Any suggestions welcome
Thanks
Dann
If the images are too big, and you are creating many Bitmaps, you'll have either to properly scale the Bitmaps before usage in code, or the shrink your resource images, if they are included in your project.
Also you have to properly use bitmap.recycle() when you no longer use your Bitmaps. This means that setting an Object which contains an Bitmap to null or clearing an ArrayList of Bitmaps won't be enough. You'll first have to iterate over the Bitmaps and call recycle() and clear then the list.
I am trying to decode a bitmap with pixel size 1024*683 with the api
decodefile(filepath) but process runs out of memory while decoding the
image.
I need the bitmap object for this image at one go without any scaling
as i have to work with NDK reading the pixel values using this bitmap.
Therefore any scaling or sampling method can't be applied in my case.
I wonder how come this is possible that just decoding a file with
such size would need any in-around method. There is enough heap size
available for this process.
Your opinion and perspective in this matter will be appreciated.
Thanks
Nawab
I faced the same problem when I had memory leaks in one of my activities. There were not only view leaks, but bitmap leaks too. And memory consumed by bitmaps is not taken into account when DDMS shows free heap space.