My activity has listview and (apart from all other stuff) loads images from web and displays them in listview. I have access to 5 android devices: 2 HTC desire, LG P-350, one more phone and a tablet. Normally, everything works fine, but being launched on one of HTC desire, app tends to crash with NullPointerException, which is due to out of memory error (I guess so), this is the output:
05-03 14:41:23.818: E/dalvikvm(843): Out of memory: Heap Size=7367KB, Allocated=4991KB, Bitmap Size=16979KB
Later, logcat outputs stack trace of nullpointerexception where one of my static variables suddenly becomes null (the variable is initialized in app's root activity, is used across the app and for sure is not nulled in code). I suppose, it is nulled by system due to lack of memory.
As far as I undesrstand, system tries to allocate bitmap as large as 17mb - I'm sure loaded images cant be that big. They are 100*70 jpegs and any of them weighs far less than 1mb.
Another thing I dont understand is why I get this error only on one device - other devices work fine.
To my mind, this looks very strange and I can find no clue, I need advice.
The reason is simple: the memory is not holding your JPG data per say, but rather its decompressed equivalent, which, needless to say, takes a lot more RAM space than the source files... Note that this 17 mb limit is for all your loaded bitmaps at once, not necessarily a single one.
I had to fight with similar problems in one of my programs (a custom Tile loader for a Mapquest Android API MapView object), and I ended up having to call the recycle() method of my bitmaps whenever possible, as well as manually oblige the system to garbage collect at strategic locations using System.gc()...
Sorry to not be the bearer of the best news...
You might solve your problems using the same strategy as I did: I essentially cache the loaded bitmaps in hard storage such as my external SD card, and reload them on the fly when needed, instead of attempting to hold everything in RAM.
Related
This is the case when I want to simulate an Out of memory crash in my application. I have a lot of crashes from Crashlytics which indicate that end users are running into OOM crashes and I have not been able to reproduce them with my device (Samsung S4). I just have crashes and no other traces from crashlytics.
I was wondering if someone has a way to reproduce them for their testing (without any code change preferred).
I saw this : Testing Android for Out of Memory scenarios , but haven't got a chance to run it yet.
Any help would be appreciated.
There are a variety of ways to cause OOM.
Use a very large image (incidentally, this use-case is a source of many real OOM issues in apps). I replaced the image for 1 element in my Recycler, so when I scroll to it, it will load the large image (then I can drive the test that way).
Create a loop, that allocates objects to memory. You can just "new" up a bunch of objects in a loop, and run it that way. If you allocate enough Strings, or int objects into a single array, this will run OOM eventually (this is also a good way to gradually build to an OOM condition). Strings will cause OOM faster then ints (but add enough objects to an array, and eventually it will become too large).
I was able to simulate the OOM error by replacing a list of images in the app very large images. 5mb instead of usual 250k. Wikimedia has lot large images you can use. https://commons.wikimedia.org/wiki/File:Snake_River_(5mb).jpg
I hope I'm understanding the question correctly: There's a very easy way if you don't want to change a lot of settings. Go into dev options and make it "no background processeses". Now you can exit out of the app, launch a new one and go back into your original and it'll be wiped out from out of memory
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.
I'm making a sketching app, mostly for fun. But i've run into a problem.
Within my app, the user can "flip" through sketches they've already drawn. These sketches are just 400x800 Bitmaps. But i'm constantly running into out of memory errors.
Sketches are saved to SD as soon as the user flips away from them, and they are then deallocated with...
if(bitmap != null)
{
bitmap.recycle();
bitmap = null;
}
So, only one or two Bitmaps should be loaded into memory at any given time, before they are saved and deallocated. And with a few debug prints, i've determined that this is true (max. two bitmaps in memory at the same time). My problem is that after 14 loads/deallocations, the program crashes with an OutOfMemoryError. Always 14, no matter how long i wait between "flips".
I've tried opening DDMS to see what the device's memory allocation is like. Strangely, every time an image is deallocated, memory goes to the "unknown" section, instead of the "free" section. This continues until there is only a sliver of "free" memory left, at which point the crash occurs (and the "unknown" memory goes to "free").
After a lot of googling, i've found a few resources which say that bitmaps should be deallocated as expected, and that Dalvik garbage collections always occur before an out of memory error. And a few miscellaneous pages that suggested that ALL memory used by a Bitmap is deallocated upon GC (native and JVM heap alike)
I should note, at this point, that i'm testing on two different phones. Motorola Droid X (stock image, Android 2.3.3), and Samsung Galaxy S3 (Cyanogenmod 9, Android 4.0.4). Both exhibit the exact same behavior. My android tools are up to date with all SDK versions, and i've checked a million times to make sure that nothing else in my code is doing any weird allocations (practically nothing is allocated after program startup).
So, how should i properly deallocate a Bitmap so that it is freed (not just "unknown"), and i can use the memory elsewhere?
As a sort of supplemental question, what is this "unknown" memory pool, and what is it for?
EDIT: Grammar and spelling, added some notes on platform.
Use large image (also 1mb near). You may be use androidmanifest in application tag set large heap true.and than use custom View not use imageview (because too complex and need more than other views)
I'm reading this question because I have to load a ton of downloaded resources into an app I'm writing, and was curious if there was a dramatic performance hit in doing so [vs. having them in the .apk], and the "correct" answer to the question implies that while there is no performance degradation, you have to worry about releasing the memory back when you're done with it, lest it leak.
Can anyone confidently confirm or deny this? My impression was that a loaded Drawable was GCed just like everything else when the Activity it was cleaned up. I'd very much like to know if that's not true, and what the most reliable way to manually collect the memory in said instance is.
Also, does anyone know if there's a noticeable performance hit in loading images from the SDCard, vs. from the phone's memory. I'm not an electrical engineer, so, intuitively, it seems like since this is all solid state memory, it should all get read at about the same pace, but I'd love to get a definitive answer.
Quick answer:
Bitmaps take two passes of the garbage collector to clean up. The first pass releases the Java object, the second pass the native pixel data. They don't leak, but you can run out of memory between when you null the pointers and the GC hits its second pass over them. This is true no matter what resource they come from. It's always a good idea to call recycle() on a bit map when you're sure both you, and the system, are done with them.
Gingerbread is particularly bad in dealing with out of memory issues and bitmaps due to a bug in the Dalvik VM.
In my experience, loading images out of the apk is MUCH faster than off the SD card.
1) They're zip aligned in the apk (if you align your apk, which you should)
2) Different phones have different access times to the SD card. The general rule is, if it's on the sd card, it's going to load SLOWLY. You can get away with loading drawables from the internal memory on the main thread (even though it's a bad idea). You cannot load anything from the SD card on the main thread. Ever :-\
If I were you, I'd be as lazy as possible when loading images, I'd keep them in the apk if possible.