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.
Related
I'm using vectordrawable for displaying images. The images are all resources which are bundled with the app (apk). My problem is, that the memory on every new activity massivly get higher until the app crashes with an OutOffMemoryException.
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:903)
at android.graphics.Bitmap.createBitmap(Bitmap.java:880)
at android.graphics.Bitmap.createBitmap(Bitmap.java:847)
I've looked into MAT for memory leaks, but did'nt find out any more than the bitmap errors.
What are the efficients way to display vectordrawables? Maybe the general architecture of my app isnt right with the activity lifecycle?
I didn't find any informations about the common memory ussage of other apps (facebook, aibnb, whatsapp,..). My usage is around 40-70MB.
There are a few things to be careful about when dealing with images:
Are you loading your images every time when you show them? This can be a potentially very memory consuming operation. It's better to load the images into memory once and then reuse them across the app.
Are you cleaning the memory occupied by the images you no longer use? If you are sure that an image is no longer needed, you should clean the allocated bitmap memory by calling bitmap.recycle(). This invalidates the bitmap and frees all the occupied memory, making it available for other operations.
Are the images too large? There is a limit for the maximum size of a single image. Trying to load a bigger image will also cause an OutOfMemoryError, even though memory can be available. In that case, you may want to optimise the image files that you are trying to load.
Go though your app and check for those potential problems one by one. Also, there are good profiling tools available for the Android platform. They can show you potential problems with the memory management, like excessive memory allocation, etc.
Good luck.
Guess what, another Android-Bitmap-OOM question!
Background
Whilst stress testing our application it has been noted that it is possible to max-out the app's process memory allocation after sustained, heavy usage (monkey runner like) with OutOfMemory exceptions being recorded within the ensuing stacktrace. The app downloads images (around 3 at a time) when a page under a ViewPager is selected. There can be 280+ images available for download when the length and breath of the app is exercised. The application uses Picasso by Square for it's image downloading abstraction. Notably, at no point in our application's code are we manipulating Bitmaps directly...we trust that the very talented Square Inc. employees are doing it better than we can.
Here is a picture
The below plot shows the heap allocations over time recorded under the dalvikvm-heap log message. The red dots indicates a user bringing a fresh set of articles into the application in order to bolster the amount of work outstanding and stress the app...
DALVIKVM heap allocations http://snag.gy/FgsiN.jpg
Figure 1: Nexus One heap allocations; OOMs occur at 80MB+
Investigation to-date
Against a Nexus S, Nexus 4, Wildfire, HTC Incredible and a myriad of further test devices, anecdotal testing has shown the memory management to be sufficient with the DVM GC 'keeping up' with the heavy lifting work being completed by the app. However, on high end devices such as the Galaxy S II, III, IV and HTC One the OOM are prevalent. In fact given enough work to do, I would imagine all of our devices would eventually exhibit the failure.
The question
There is clearly a relationship between screen density (our requested image sizes are based off the size of the ImageView), the process memory allocation and the number of images at a given size that would result in the app exceeding it's heap limits. I am about to embark on quantifying this relationship but would like the SO community to cast their eyes over this problem and (a) agree or disagree that the relationship is worth making and (b) provide literature indicating how best to draw up this relationship.
It is important to note that if we destroy the image quality our OOM all disappear but alas the UX is poorer which is why we are wanting to be dicing with the most effective use of the available heap.
Side note: Here is the portion of code responsible for loading these images into the views that have been laid out;
picassoInstance.load(entry.getKey())
.resize(imageView.getMeasuredWidth(),
imageView.getMeasuredHeight())
.centerCrop()
.into(imageView);
The 'dashing of image quality' mentioned above is simply dividing the imageView.getMeasured... by a number like '4'.
First you need to manage the memories allocation ,its a big issue in android as bitmaps takes lots of memories ,for that memory allocation can be reduce by following ways
put all those images which are huge in size to assets folder instead of putting them in drawabable folder . because drawable resources takes memory for caching them .if you load from asset folder the image will not cache .and will takes less memory .
study Lrucache which use for efficient memory management .
put resources in tiny formats for that check TinyPNG
if your images are too large in resolution , then try to use SVG files for images and load SVG file instead of image . check this SVG FOR ANDROID
finally i am not very good in English hope it may helps you.
This post is a little old but I also had this issue recently. Maybe this will help someone else.
General Overview of this massive thread/What helped me.
-Make sure you are using a Singleton Instance of Picasso
-Use fit()
-For large Images or many Images or when used in a FragmentPager/StatePager you should probably use skipmemorycache() and/or largeHeap declaration
Read the thread for more tips. At the time this question was posted nobody had posted this issue on picassos github.
https://github.com/square/picasso/issues/305
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?
I'm working on a graphical app for which I want to keep an array of bitmaps that are used for Undo operations. The bitmaps are quite large at around 9M each, so I realise I can only keep a few in memory at any given time.
I'd like some way of working out in advance how many I can have.
I've tried various ways of querying available memory, and am being careful to recycle bitmaps once they are not needed, but despite that the app seems to crash with EOutOfMemory.
I don't want to scale down the bitmap, or use RGB565. I just want a reasonably reliable way to figure out how many undo steps I can allow for.
Thanks
EDIT #1
I've continued to try various ways of determining available memory, including those linked to in the comments, but still am having problems.
The strange thing is that my old Samsung I9000 phone doesn't have too many problems creating and accessing lots of bitmaps each 9MB in size, but my newer Samsung Tab 3 dies allocating the 3rd one.
It should have plenty of memory available. I did read something about there being differences in where memory is allocated for bitmaps on Android 3 and above, but don't fully understand it. Could this be what is causing my Tab to die with EOutOfMemory?
EDIT #2
In desperation I decided to turn on largeHeap in the manifest. I know it's not recommended, but it has made the Tab 3 behave more predictably, and it possibly demonstrates something about the underlying problem.
This reminds me of a very common mistake , of putting the image files into the "res/drawable" folder.
Such a thing causes the bitmaps to take much more memory the higher the screen density is.
for example, for a 100x100 image, it would take only 100*100*4 = 40,000 bytes on an mdpi device, but it will take (2*100)*(2*100)*4 = 160,000 bytes on an xhdpi device (4 times more).
however, since the galaxy tab 3 doesn't seem to have a high density screen, i think that you get OOM because the heap size is small for holding all the bitmaps.
check out my post here for some memory and bitmaps tips.
It seems that getting available memory is a bit quirky in Android, but it turned out that my main problem was that on newer versions of Android the memory allocation for bitmaps has changed, and they now easily blow the limit of the heap.
Setting largeHeap in the manifest got me around that problem, but I'm still not sure it's ideal.
Describing background, as I may just have a terrible approach to the problem - self learning.
I'm writing an app for android, and testing it on default AVD, which is set to WVGA800 with 512 'device ram size' and 240 'Abstracted LCD density'.
I have some images, and I put them into drawable-hdpi.
There are 458 KB (not MB) worth of images in that folder.
All images are in PNG format.
The issue is that when I try to load my biggest image (used for background), it throws: java.lang.OutOfMemoryError
This is the call to load the image:
BitmapFactory.decodeResource(status.getResources(), R.drawable.background);
This is identical to how I load the rest of images (33 in total).
It makes sense to me, that it would run out of memory on biggest image, but my total size of folder is 458 KB, so I wouldn't expect to run out of 512 MB Ram set on device.
I never unload any images, I keep them loaded, and use as needed.
I wrote a different app before, where my total size of images was 563 KB with 82 images total, and I didn't have this issue (using the same AVD). In fact the prior app used to make a couple of copies of each image by flipping it, and still didn't run out of space. Current app is failing on initial load - before much happened.
Could someone point me at what the issue could possibly be? And how I can solve it, or maybe mention if my approach is wrong (self-teaching myself from examples)
I'll give you some hints on how i manage to lessen that problem
If you plan to support all devices, put all your resource into the xhdpi folder. especially the background
File size != memory size
Keep in mind a few things:
Your application has a memory limit (this depends on the android version). You don't get all the device memory. I think that first android version have a memory limit of 16mb.
The size of the file doesn't represent the size of the bitmap in memory. For example a 32bit ARGB bitmap will take 32*width*height bits
If you are dealing with big images then scale them first. Calculate the size you need (this will probably be the size of your ImageView) and load a resized copy of the bitmap. You can do this using BitmapFactory.Options
Yea, this is a pretty common problem. So in older versions of android OS, the bitmap was loaded into native memory and not the JVM. The garbage collection process would really have 2 cycles. One to clear out the memory in the JVM and the other to clear out the memory in the native memory (for bitmaps). If you want to work on older devices, you will need to handle this situation by either recycling your bitmaps Bitmap.recycle() or calling System.gc()
There are two problems that you might be hitting:
1. You have other bitmaps that are un recycled.
2. You really are running out of memory because that single image is too big. (Make sure the other images are correctly recycled or gc'd so that it doesn't add to the memory footprint). In this case, no much you can do.
ALso, as mehmet suggested, you can read this