Closed GoogleCodeExporter closed 8 years ago
It sounds like the issue here is that if we are in a low memory situation, then
the filesystem provider will OOM, which will then proceed to the tile download
provider. The tile download provider will then download the data, try to create
a Bitmap, and OOM. So the phone downloaded the data from the Internet and has
nothing to show for it. The screen then gets refreshed causing another tile
request and more wasted data traffic.
It's a tough situation - how do we know we are in a "major failure" situation
and then how do we know when we've recovered?
I think one way we can greatly limit the impact of this situation is to throw a
CantContinueException from the TileDownloader when we get an OOM. This will
clear the pending queue for the TileDownloader, preventing needless download +
OOM cycles, while still allowing at least one tile request to determine if we
are still in a low-memory situation. We will probably have to have make
ITileSource.getDrawable throw OOM rather than return null and require the tile
providers to handle the exception so they can throw CantContinueException.
Original comment by kurtzm...@gmail.com
on 6 Mar 2011 at 2:02
Java purists are suggesting to not even catch OOM:
http://stackoverflow.com/questions/1692230/is-it-possible-to-catch-out-of-memory
-exception-in-java
but maybe in our case it's applicable since we are dealing with sizable
allocations and we have a cache where we can reclaim memory to make room.
There is a lot of talk about using SoftReferences. This seems like a great
solution, but apparently SoftReferences are broken in Android 1.5 - 1.6:
http://www.mail-archive.com/android-developers@googlegroups.com/msg47879.html
http://stackoverflow.com/questions/4337285/android-heap-size-and-softreferences
http://stackoverflow.com/questions/4014033/android-the-gc-doesnt-respect-softref
erences
So, maybe when we get an OOM the behavior should be to make a call to something
like mTileCache.freeLRUTile() and then to try again. This would allow
downloaded tiles to download and (eventually) properly render and save to the
file cache. The unfortunate visual side-effect of an OOM situation would be
"flashing" loading tiles on the screen since there isn't enough memory for all
tiles on the screen in the cache. Also, the app would stutter as the GC hammers
the system.
I am not an Android memory expert, so is it reasonable to assume that if we get
an OOM even after a GC that we will eventually get some memory back for our
process and recover? Looking at the responses in the first link, it sounds like
once you hit OOM, you're on the road to ruin and you can't really recover. So,
what is our best-case scenario during a low-memory situation? Should we try to
run things the best we can and perform poorly, or should we gracefully refuse
to display tiles until the user frees up some memory? Perhaps offer the option
of both?
Original comment by kurtzm...@gmail.com
on 6 Mar 2011 at 3:10
I am submitting the following patch as the solution described in comment 1. We
bubble up a LowMemoryException to the tile provider modules, who then throw a
CantContinueException which causes their tile request queue to clear.
Original comment by kurtzm...@gmail.com
on 6 Mar 2011 at 4:01
Attachments:
I don't know which is the best way to recover from low memory situations, but I
am sure that a waste of data traffic must be prevent in any case. Even a
termination of the app as worst case scenario would be better than that.
In consideration of the fact that an OOME should be a very seldom exceptional
event, I even would accept an error message, followed by the termination.
Original comment by sepp.dot...@googlemail.com
on 7 Mar 2011 at 8:41
I am going to apply this patch, and close this ticket. I think the idea of
allowing an optional "Low memory warning" fallback view is worth exploring so I
will add a new ticket for that.
Original comment by kurtzm...@gmail.com
on 11 Mar 2011 at 5:16
Fixed by r870
Original comment by kurtzm...@gmail.com
on 11 Mar 2011 at 5:31
Original comment by kurtzm...@gmail.com
on 11 Mar 2011 at 5:31
Original issue reported on code.google.com by
sepp.dot...@googlemail.com
on 4 Mar 2011 at 2:01