p-lr / MapCompose

A fast, memory efficient Jetpack Compose library to display tiled maps, with support for markers, paths, and rotation.
Apache License 2.0
220 stars 19 forks source link

Tiles of size smaller than specified to `MapState` are not garbage-collected #101

Closed TimPushkin closed 9 months ago

TimPushkin commented 10 months ago

If TileStreamProvider returns a stream of an image of resolution smaller than specified to MapState as tileSize (e.g. tileSize is 256, but the provider returns a 128x128 image) such tile will be displayed correctly (it will be upscaled to the required size), but it won't be garbage-collected until the whole MapState has been. So, for example, if I will be scrolling such tile off the screen and back it will be loaded as a new object each time and eventually I'll get an OutOfMemoryError.

I expect to be asked why does my provider return tiles of smaller sizes, and the reason is indeed pretty awkward: my maps have a lot of fully transparent tiles with no content and I've decided to replace such 256x256 tiles with 1x1 tiles to save space. I know MapCompose allows providers to return null, but for some reason on the phone I use for testing I experience severe lag when null tiles are present (same on MapCompose demo app). I don't experience this lag on other phones, though, so I'm currently investigating this (I should probably open a separate issue or discussion for this). Just wanted to share the GC issue since for me it was rather unexpected.

p-lr commented 10 months ago

I suggest that you reproduce it in a fork of the demo app, so I can investigate. At this point I can't tell whether the TileStreamProvider returning tile with inappropriate size can be gracefully handled or not.

TimPushkin commented 10 months ago

Reproduced here: https://github.com/TimPushkin/MapCompose/tree/gc-bug

I modified the tile provider to return 128x128 tiles instead of 256x256. You can use "Simple map" demo to see that the memory is not freed until the demo is closed.

p-lr commented 10 months ago

I can confirm that sending 128x128 tiles results in the BitmapPool growing in size indefinitely.

p-lr commented 9 months ago

I have pushed th try-fix-#101 branch, which fixes the issue on my side. Please let me know if that fixes the issue on your app.

p-lr commented 9 months ago

As for:

I know MapCompose allows providers to return null, but for some reason on the phone I use for testing I experience severe lag when null tiles are present (same on MapCompose demo app). I don't experience this lag on other phones, though, so I'm currently investigating this (I should probably open a separate issue or discussion for this).

Could you open a separate issue?

TimPushkin commented 9 months ago

I have pushed th try-fix-#101 branch, which fixes the issue on my side. Please let me know if that fixes the issue on your app.

Tried it and it looks like the issue is fixed, thanks!

Btw, when I accidentally tried to build MapCompose's tests there was an error because Bitmap.Config is passed somewhere where BitmapConfiguration is expected. I see there are some related changes in try-fix-#101, so you probably just haven't adapted the tests yet.

As for:

I know MapCompose allows providers to return null, but for some reason on the phone I use for testing I experience severe lag when null tiles are present (same on MapCompose demo app). I don't experience this lag on other phones, though, so I'm currently investigating this (I should probably open a separate issue or discussion for this).

Could you open a separate issue?

Sure, I'll record a video demonstrating the lag and open the issue.

p-lr commented 9 months ago

Yes, I had to fix the tests, thanks. I'll probably make additional tests before making a new release.