Bug 37250 - Activity Finalizer invoked even when Disposed
Summary: Activity Finalizer invoked even when Disposed
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 5.1
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2015-12-22 20:08 UTC by Alexandre Emond
Modified: 2017-07-13 19:52 UTC (History)
4 users (show)

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


Attachments
Xamarin and WPF Android sample (64.06 KB, application/x-zip-compressed)
2015-12-22 20:09 UTC, Alexandre Emond
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 Alexandre Emond 2015-12-22 20:08:07 UTC
https://bugzilla.xamarin.com/show_bug.cgi?id=37249

Even if we call an Activity.Dispose() which in turn call the GC.SuppressFinalize(this), the Finalizer is still invoked

Overview

The Xamarin Garbage Collector is not reacting the same way as in .Net, which is probably cause the Activity memory to be collected way after  than it should be. This cause issue with Activities using lots of memory (eg.: Image manipulation)

** Steps to reproduce with the Xamarin Sample ** 

- Click "Go To Sub" to navigate to the SubActivity (Create a new instance of an Activity)
- Go back from the sub activity (Release the reference of the Activity, and calling the Dispose shortly after the Activity.OnDestroy)
- Click "GC.Collect()"
- Click "GC.Collect()" a 2nd time
- Click "GC.Collect()" a 3rd time

OUTPUT:

- Handle=1049854
- SubActivity Dispose (True)
- Handle=0
- GC.Collect ()
- SubActivity JavaFinalize ()
- 1 managed SubActivity alive  *** Randomly switch between 0 an 1 managed SubActivity alive at ~50% ratio
- GC.Collect ()
- 0 managed SubActivity alive
- GC.Collect ()
- SubActivity Finalizer called
- SubActivity Dispose (False)
- 0 managed SubActivity alive

** Steps to reproduce with WPF to compare the GC behavior **

- Click "Create instance" (Create a new instance of TestA an release the reference right after)
- Click "Dispose known instances"
- Click "GC.Collect()"
- Click "GC.Collect()" a 2nd time
- Click "GC.Collect()" a 3rd time

OUTPUT:

- TestA Dispose()
- TestA Dispose (True)
- GC.Collect()
- 0 managed TestA alive
- GC.Collect()
- 0 managed TestA alive
- GC.Collect()
- 0 managed TestA alive

** Actual Results **

- In the Xamarin app, the Activity Finalizer is called even if Java.Lang.Object.Dispose has been call (which called GC.SuppressFinalize and set Handle to 0)
- In the Xamarin app, the Activity randomly stay alive after the first GC.Collect()

** Expected Results **

- In the Xamarin app, the Activity Finalizer is not called called when Java.Lang.Object.Dispose has been called()
- In the Xamarin app, the Activity get collected after the first GC.Collect() after a .Dispose()

** Additional Information , Build Date & Hardware **

In the WPFSample, you’ll see the TestA class that implement the IDisposable pattern correctly. It simulate the Java.Lang.Object (which Activity inherits from) implementation, but without the handling the JNI (unmanaged). The particularity of that last one is it can ReRegisterForFinalize in case the Java handle is non-zero to ensure the cleanup.
-	protected virtual void Dispose(bool disposing) : Invoked by an Explicit Dispose() or by the Finaliser
-	public void Dispose() : Which call Dispose(bool disposing) + suppress the Finalizer call
-	~TestA() : Which call Dispose(bool disposing)

Emulator Android API 22 Nexus 4
Visual Studio 2015 (14.0.24720.00 Update 1) on Windows 10
Xamarin   3.11.1594.0 (a06d6d5)
Xamarin.Android   5.1.7.12 (53fce3730830417896a42f365a5ba35f1ee58d9d)
Comment 1 Alexandre Emond 2015-12-22 20:09:29 UTC
Created attachment 14387 [details]
Xamarin and WPF Android sample
Comment 3 Cody Beyer (MSFT) 2017-07-13 19:52:22 UTC
Unfortunately, we’re unable to reproduce this report. If this issue is still occurring for you, please reopen this issue and attach a reproduction to the bug by starting with a clean Xamarin.Android project adding just the code necessary to demonstrate the issue.