Bug 40970 - Memory Leak in the Xamarin Forms Maps component on iOS
Summary: Memory Leak in the Xamarin Forms Maps component on iOS
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-05-09 16:30 UTC by Chad Cook
Modified: 2017-03-28 21:03 UTC (History)
8 users (show)

Tags: ac
Is this bug a regression?: ---
Last known good build:


Attachments
Sample Project (271.63 KB, application/zip)
2016-06-01 00:10 UTC, Chad Cook
Details
Updated repro project (50.05 KB, application/x-zip-compressed)
2016-08-20 00:42 UTC, E.Z. Hart [MSFT]
Details
Test project and test results (4.38 MB, application/zip)
2017-02-24 19:25 UTC, Rob DeRosa
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Chad Cook 2016-05-09 16:30:56 UTC
I've been using the Xamarin.Forms.Map on a project, but it looks like there might be a memory leak within the component.

When inspecting memory usage with the profiler, every time I navigate back to the page with the map, memory usage jumps up a lot, like it's never being garbage collected, even after the page that it was added to has been popped off the navigation stack.

As a proof of concept I made this really simple two page forms app (attached). (Note that I didn't set this up to work on android, so not sure if it's an issue there too)
Comment 1 Bryan Hunter 2016-05-31 22:43:19 UTC
Hi Chad. In your comment you mention the a reproduction is attached, but it appears the attachment is missing. Can you please attach a reproduction?

For your convenience, we have created some reproduction best practices viewable here: https://gist.github.com/jassmith/92405c300e54a01dcc6d

Warm regards,
Xamarin Forms Team
Comment 2 Chad Cook 2016-06-01 00:10:28 UTC
Created attachment 16148 [details]
Sample Project
Comment 6 E.Z. Hart [MSFT] 2016-08-20 00:42:18 UTC
Created attachment 17133 [details]
Updated repro project
Comment 7 E.Z. Hart [MSFT] 2016-08-20 01:14:04 UTC
The original repro project doesn't force the garbage collector to run at deterministic times, so the memory usage will continue to grow until the application needs to reclaim memory. I've uploaded a modified version of the project (attachment 17133 [details]) which forces the garbage collector to run and changes a few other things to better illustrate what's happening:

a. When a page is popped off the stack, GC.Collect() is called to force garbage collection to run. The original reproduction did not do this. By forcing it to run, we can observe destructor and memory behavior at each step.

b. Usage of Map has been replaced by a subclass called MyMap which writes to the debug output when its constructor and destructor are run, so we can see when the garbage collector collects it. It also tracks the current number of MyMap instances allocated.

c. An additional root page has been inserted into the navigation hierarchy so we can see what happens when the map page is not the page most recently popped off the stack. 

To see that the Map instances *are* being garbage collected (and not leaked), use the following steps:

1. Run the application; on the root page, tap 'Start'. 

2. On the next page, tap 'navigate to map page'. In the debug output, you should see a message that an instance of MyMap has been allocated. 

3. Tap the 'Back' button. The garbage collector will run. In the debug output, you should see a message indicating the amount of memory currently allocated. Note that the MyMap destructor is *not* called. This is because the NavigationPage needs to keep a reference to the last popped page. 

4. Tap the 'navigate to map page' button. In the debug output, you should see a message indicating that the Map constructor was called, and there are now 2 instances of MyMap allocated.

5. Tap the 'Back' button. The garbage collector will run. In the debug output, you should see a message indicating that the destructor has run, and there is now only 1 instance of MyMap allocated. 

6. Repeat steps 4 and 5 as many times as you like; each time step 5 is repeated, the number of instances of MyMap will be 1. Also note that the total memory allocated remains relatively constant.

7. Tap the 'Back' button to return to the root page. The garbage collector will run. Depending on the timing, the destructor for the last instance of MyMap may be called (its availability for garbage collection is asynchronous, and it may not be collectable at the time the GC runs; if the destructor message doesn't appear, tapping 'Start' and then 'Back' to forec the GC to run again should do it).
Comment 8 Guilherme 2016-08-22 16:53:22 UTC
I'm still seeing the same problem happening, on Android, with your sample project. The instances of the Map are being destructed and the memory allocated stays stable, but the GC_EXPLICIT keeps getting bigger and the app crashes without a warining/error. Is this maybe an android specific problem ?
Comment 9 Mark 2016-08-23 08:28:29 UTC
Same problem here on android. Just download the "updated repro project" and test it on android device. Desctructor is called but memory increases until app crashes. Even tried to use the newest packages, but no changes!
Comment 10 E.Z. Hart [MSFT] 2016-08-29 16:48:52 UTC
(In reply to Mark from comment #9)
> Same problem here on android. Just download the "updated repro project" and
> test it on android device. Desctructor is called but memory increases until
> app crashes. Even tried to use the newest packages, but no changes!

Mark,

I'm currently running the updated repro project on a Nexus 6 device with API 23 and I'm not observing any crashes after pushing/popping the maps page several dozen times. This is with the latest stable (2.3.1.114). 

How many times loading the maps screen does it take for the app to crash for you? What hardware/emulator (and API version) are you running on?
Comment 11 E.Z. Hart [MSFT] 2016-08-29 16:51:04 UTC
(In reply to Guilherme from comment #8)
> I'm still seeing the same problem happening, on Android, with your sample
> project. The instances of the Map are being destructed and the memory
> allocated stays stable, but the GC_EXPLICIT keeps getting bigger and the app
> crashes without a warining/error. Is this maybe an android specific problem ?

Guilherme,

Does the crashing persist if you update to the latest version of the XF nuget packages? Some (non-maps-related) memory leak issues with navigation pages on Android were addressed in the last couple of updates; if you're running on 2.1.0.6529 you may be running into those issues.
Comment 12 Guilherme 2016-08-30 14:17:58 UTC
I'm using a Samsung Galaxy tab 3 10.1', with api 19 and the same version of xamarin.forms as you (2.3.1.114). The crash happens after navigating in and out of the page with the map for about ~40 times. In the device RAM manager i can see the alocated ram for the application increase until the crash happens.
Comment 13 Mark 2016-08-30 14:59:41 UTC
I don't use any emulator. Just Samsung S3 and A5 2016. Android 6.1, 5.1.1 and some old 4.2.

But I solved the Problem! Custom MapRenderer, and in Dispose() just call:

var map = this.Control as MapView;
map.OnDestroy();
map.Dispose();

It is already mentioned here:
https://bugzilla.xamarin.com/show_bug.cgi?id=39489
Comment 14 Guilherme 2016-08-30 15:02:04 UTC
Do you mind sharing a sample project ?
Comment 15 Rui Marinho 2016-09-27 10:56:38 UTC
Should be fixed in 2.3.4-pre1
Comment 16 E.Z. Hart [MSFT] 2016-09-27 16:25:57 UTC
Reopening - the Android side of this is fixed, but there are still some potential iOS issues I want to look at.
Comment 17 Rob DeRosa 2017-02-24 19:23:35 UTC
Client has confirmed this is still an issue on iOS. I've attached profiler log, test project and screenshots.

Forms Version: 2.3.3.193
Platforms: iOS
Comment 18 Rob DeRosa 2017-02-24 19:25:15 UTC
Created attachment 19954 [details]
Test project and test results