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
Related
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 have an app that downloads a csv file online then saves it locally so the app will work even if it is offline. My problem is when the user closes the app then opens it again immediately, the app hangs while parsing the saved csv file and throws OutOfMemoryError. However, I noticed that when I open the app again after a few minutes it works just fine.
The downloading, parsing and saving are done on separate threads.
What can be the solution to this?
One possibility: out-of-memory errors can have more to do with an overworked GC than with an actual shortage of memory. If you allocate large pieces of memory, then free them, then allocate even larger pieces, you get to a point where you have a lot of large bits of free memory taking up space but unusable because they're not large enough. The GC is frantically trying to move things around and merge these pieces into one contiguous block for the next allocation, but rather than look bad because it's taking too long, it will just throw an OutOfMemory exception, even though 90% of memory is theoretically available (and will be available if you can give it a minute).
In your case, I'd suspect ArrayList. It keeps an array of references. As you add entries, it adds to the array. When it runs off the end, it allocates a new, bigger, one and frees the old one. These discards pile up if you keep it busy. Hashtables have similar problems. LinkedList and TreeMap don't, because they work with small bits of memory.
I don't know too much about Android, but I'm guessing the app doesn't really close when you close it briefly, so when you restart it it's the same free-memory-fragmented execution as before. If you wait a while it may be a new execution. Even if it's not, the GC has had time to clean things up and you're fine.
The solution you want is probably to force a garbage collection (System.gc()) each time you "start up" your system. It gives the GC a chance to put everything in order before allocating space for you, and it won't take long. In a sense, you're giving the GC permission to lock up your program for half a second, which it would not do on its own. (And if it did, it would pick an awkward time to do it--while the user's entering text, say.)
Avoiding large arrays by using linked collections is another solution, but arrays are fast and when you can spare a half-second of the user's time there's no reason to switch.
Hope this helps. If it's not the problem this time, maybe it will be next time.
Addition: Unfortunately, System.gc() is just a "suggestion". It may not be doing the job we hoped it would do. Or you may be getting into trouble after the call. The other big fix I should have mentioned before would be to set the initial size on ArrayList very large, if that is what your are using. Making it two or three times the size it needs to be will probably save you ten times that amount of memory over a run--and save time, too. This works for any array-based structure (hash tables and plain arrays). Beyond that, pointer-based structures like LinkedList will not have this problem if you can get around their disadvantages.
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.
Noob question!
My whiteboard/drawing app runs fine, using a combination of simple image views and bitmaps with me rendering a path to a bitmap and copying over as needed. I have it multitasking on my ICS Transformer without problems. However, if I exit the app with the Back button and then run it again, it fails; I get a memory error on the second run when I try to draw something.
Out of memory on a 4096016-byte allocation
Although sometimes I don't get that and it runs a second consecutive time. When I run it a third time, it works, and the fourth, again it Out-of-memory's.
What manual cleanup do I have to do when an Android app exits? Should I remove all created objects and bitmaps and paths and listeners and stuff?
Looks like you have a memory leak. Make sure you follow recommendations provided here. Often Memory Analyzer Tool is very useful in such cases. Here is a video how to use it.