hansjoachimbutz / osmdroid

Automatically exported from code.google.com/p/osmdroid
0 stars 0 forks source link

out of memory when switching between map activities #265

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Have two seperate map activities with overlays
2. switch between them using menu driven command
3. After about 4 times backwards and forwards the map goes black (out of memory)

What is the expected output? What do you see instead?

garbage collector should clean up the memory.  It seems as though the activity 
is not released for garbage collection after onDestroy.  It worked ok with 
google maps before.

What version of the product are you using? On what operating system?

osmdroid 3.05 android 2.2

Please provide any additional information below.

I am relatively new at Java and Android so I don't really feel confident to 
start changing the source code to make it work.  I use the standard 3.05 jar 
file as an external library in intellij idea ver. 10.5.2

Original issue reported on code.google.com by mike.a.f...@gmail.com on 4 Oct 2011 at 1:11

GoogleCodeExporter commented 9 years ago
Oh I forgot to say that the out of memory error always happens on decoding 
tilemap bitmap streams from the sd card

Original comment by mike.a.f...@gmail.com on 4 Oct 2011 at 1:15

GoogleCodeExporter commented 9 years ago
The phone is an HTC wildfire,  so I guess there is not much memory available on 
this low end device to leak away unnecessarily.  On the htc desire I can switch 
back and forth about 20 times

Original comment by mike.a.f...@gmail.com on 4 Oct 2011 at 1:18

GoogleCodeExporter commented 9 years ago
There are endless issues about this and no-one has yet been able to find a 
satisfactory solution.
issue 127
issue 228
issue 238
issue 258
not to mention many closed issues

Original comment by neilboyd on 5 Oct 2011 at 8:03

GoogleCodeExporter commented 9 years ago
I downloaded the osmdroid source from the repository and studied the code a 
bit....

then tried:

_mapView.getTileProvider().clearTileCache();
System.gc();

into the onDestroy() method of each map activity....it seems to work,  no more 
out of memory even after 20 times backwards and forwards on the htc wildfire

Original comment by mike.a.f...@gmail.com on 5 Oct 2011 at 12:54

GoogleCodeExporter commented 9 years ago
First can I saw that I'm very pleased that someone is investigating this.

Now for some comments that come immediately to mind:

That may work as a temporary solution to improve the situation, but it's 
probably not solving the root cause.

The cache should be able to free it's own resources when it's not using them 
any more. It should be able to do this continuously.

Rotation is an easy way to accelerate the memory leak, but it will probably 
still happen after a long period of use without rotation.

Also, it should not be necessary to force garbage collection, and that will not 
cause anything to happen that would not have happened by itself anyway.

Please feel free to prove me wrong!

Original comment by neilboyd on 5 Oct 2011 at 1:04

GoogleCodeExporter commented 9 years ago
I think that the tilecache is just growing as tiles are decoded from the sd 
card without ever releasing any of the cached tiles again.  Perhaps a solution 
would be to selectively clear the oldest cached tiles to keep the tile cache at 
a managable size.

Anyway I am happy with my temporary solution for now as it makes my app usable.

Original comment by mike.a.f...@gmail.com on 5 Oct 2011 at 1:12

GoogleCodeExporter commented 9 years ago
as i posted in the google group i had a similar problem but only with archive 
files. But maybe it helps other to find their problem too. I'll open an issue 
for this with a detail description.

greetings
daniel

Original comment by abzy...@gmail.com on 12 Oct 2011 at 10:33

GoogleCodeExporter commented 9 years ago
Perhaps the fix suggested for issue 267 would also work for 
MapTileFilesystemProvider

Original comment by neilboyd on 12 Oct 2011 at 11:32

GoogleCodeExporter commented 9 years ago
Issue 292 has been merged into this issue.

Original comment by neilboyd on 6 Jan 2012 at 6:04

GoogleCodeExporter commented 9 years ago
Issue 127 has been merged into this issue.

Original comment by neilboyd on 26 Mar 2012 at 8:00

GoogleCodeExporter commented 9 years ago
Issue 258 has been merged into this issue.

Original comment by neilboyd on 26 Mar 2012 at 8:00

GoogleCodeExporter commented 9 years ago
Issue 353 has been merged into this issue.

Original comment by neilboyd on 29 Jun 2012 at 7:06

GoogleCodeExporter commented 9 years ago
Issue 367 has been merged into this issue.

Original comment by neilboyd on 5 Sep 2012 at 2:36

GoogleCodeExporter commented 9 years ago
As my issue 367 is merged in here, I would also like to mention that this issue 
also occurs when using in fragments

Original comment by nikhilps...@gmail.com on 5 Sep 2012 at 2:48

GoogleCodeExporter commented 9 years ago
This can be related with issue 228 and my 337. So if your got any offline map 
files, likes zips, in osmdroid folder, delete it if you dont need them. It will 
improve performance of map, and memory error will reduce to minimum. So this is 
my only advice, until the issue will be fixed.

Original comment by vbu...@gmail.com on 5 Sep 2012 at 2:54

GoogleCodeExporter commented 9 years ago
we have created tiles from an image using map tilers. and these are used as 
custom tiles. these tiles are stored on sdcard. we cannot delete this as we 
need them ... 

we need te issue to be fixed soon as our app release is stuck because of this. 
fragments in activity.... may be also a good point to consider

Original comment by nikhilps...@gmail.com on 5 Sep 2012 at 3:33

GoogleCodeExporter commented 9 years ago
what about using soft reference for cache.. will that reduce the error

Original comment by nikhilps...@gmail.com on 6 Sep 2012 at 8:06

GoogleCodeExporter commented 9 years ago
I suspected that the current cache can't actually detect when it's to big. 
After looking through the code I didn't find anything that actually clears it 
so I went ahead and developed a fix.

The android support library contains an implementation of a LRU Cache. I 
replaced the MapTileCache inside the MapTileProviderBase with this. It wasn't 
that hard just changing some function calls.

Only take care to choose the right size. If you choose your cache too small it 
will constantly load new bitmaps and then quickly GC them again so I set the 
size to a beefy 16M and never had a problem again.

Original comment by reinhard...@gmail.com on 20 Nov 2012 at 5:42

GoogleCodeExporter commented 9 years ago
I read this: 
http://stackoverflow.com/questions/5523552/bitmapfactory-options-intempstorage-f
ield

In BitmapTileSource.getDrawable(), I replaced

   final BitmapFactory.Options options = new BitmapFactory.Options();
   options.inTempStorage = new byte[32768];
   final Bitmap bitmap = BitmapFactory.decodeFile(aFilePath, options);

by 

   Bitmap bitmap = BitmapFactory.decodeStream
     (new BufferedInputStream(new FileInputStream(aFilePath)));

which seems to help in my app. I didn't get the outOfMemory errors so far.

Original comment by christin...@gmail.com on 24 Dec 2012 at 7:01

GoogleCodeExporter commented 9 years ago
This looks like a very relevant video: http://youtu.be/rsQet4nBVi8

Original comment by neilboyd on 1 Feb 2013 at 9:01

GoogleCodeExporter commented 9 years ago
with your help, i fixed my problem.thank u,mike

Original comment by lazypi...@gmail.com on 12 Mar 2013 at 1:02

GoogleCodeExporter commented 9 years ago
I confirm the call to Bitmap bitmap = BitmapFactory.decodeStream(new 
BufferedInputStream(new FileInputStream(aFilePath))); solves the outOfMemory 
error, moreover the map scrolling is A LOT smoother (even the emulator is 
usable with plenty of overlays \o/). Why not include the code into new osmdroid 
release ?

Original comment by waeselyn...@gmail.com on 13 Aug 2013 at 9:15

GoogleCodeExporter commented 9 years ago
I managed to fix this issue on 2.3.3+. It's actually not that hard to resolve 
it. It all boils down to a simple misunderstanding about bitmap allocations in 
different versions of Android. Before version 3.0 (API 11, Honeycomb) this was 
done on the native heap, requiring one to call recycle() on each allocated 
bitmap in onDestroy() of the associated Activity.

Looking at org/osmdroid/osmdroid/tileprovider/LRUMapTileCache.java on line 45 
(my SVN version), we see the following:

  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {

When we change this to

  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {

and rebuild, the issue is gone.

Whether this issue still exists on 2.2 and 2.1 I'm not sure, but based on the 
code and my experiences on 2.3.3 I'd say it should be fixed now.

Please let me know if you want me to shoot in a patch for this.

Original comment by mayaposch on 13 Aug 2013 at 9:37

GoogleCodeExporter commented 9 years ago
Sounds curious since my project is for Jelly bean, if I get your point well, it 
should not behave this way ?

Original comment by waeselyn...@gmail.com on 14 Aug 2013 at 6:20

GoogleCodeExporter commented 9 years ago
@24 - By testing on JB (4.2.2, 4.3) I did not see the memory leak issue, 
although admittedly I gave up on testing after switching to/from the map view a 
few dozen times on the Galaxy Nexus test device.

What does your heap dump look like? Since bitmap allocations in API 11+ are in 
the Dalvik heap, it should show up in there.

Original comment by mayaposch on 16 Aug 2013 at 12:37

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I've got the issue on the SAMSUNG Note 10.1, JB(4.1.2) and nothing helps to fix 
it.

Original comment by nedoo...@gmail.com on 2 Sep 2013 at 5:28

GoogleCodeExporter commented 9 years ago
Can we solve this by using the same cache for the both activities, by making 
the mTileCache field in the MapTileProviderBase class static?

Original comment by gencic.n...@gmail.com on 19 Oct 2013 at 3:37