Bug 61050 - Garbage collector not triggered on Nougat
Summary: Garbage collector not triggered on Nougat
Status: NEEDINFO
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 8.1 (15.5)
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2017-12-08 15:28 UTC by Michael Mazur
Modified: 2017-12-18 14:29 UTC (History)
3 users (show)

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


Attachments
Demo apps - java and xamarin (7.74 MB, application/zip)
2017-12-08 15:28 UTC, Michael Mazur
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 for Bug 61050 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
NEEDINFO

Description Michael Mazur 2017-12-08 15:28:33 UTC
Created attachment 25954 [details]
Demo apps - java and xamarin

GC is not triggered on Android Nougat (7.0 on Samsung A5), app eventually crashes with java.lang.OutOfMemoryError.
I cannot reproduce this behaviour on other android versions (tried 4.4.2 and 6.0.1 on devices, 7.0 and 7.1.1 on emulator).
I prepared two demo apps (in Java and Xamarin). Java app calls finalizers as expected but in Xamarin app Dispose is never called in ViewHolders etc.
Comment 1 Jon Douglas [MSFT] 2017-12-12 22:32:07 UTC
Hi Michael,

We have GC tips in our documentation that might be helpful here:

https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/#Helping_the_GC

I've also answered a similar question here that might help you out:

https://stackoverflow.com/questions/40620486/what-is-the-correct-moment-to-call-dispose-when-using-the-viewholder-pattern

If it's possible, can you please include reproduction steps for your sample?

We have a bugzilla bug writing guide that can help out in this area:

https://bugzilla.xamarin.com/page.cgi?id=bug-writing.html

It isn't quite clear "Why" this is a GC bug on Nougat when it seems you already noticed it works in a 7.0 / 7.1.1 emulator. If you can help clear that up with some more information on your end that would really help aid our internal investigations! Observations such as: A) How long does it take to reproduce this issue and what steps one should take? B) What devices and API levels this happens on? It seems only one specific device and API level? C) Any Xamarin Profiler snapshots showing memory leaks and what types of objects are leaking.

Thanks in advance!
Comment 2 Michael Mazur 2017-12-18 09:30:44 UTC
A. Run the Xamarin app, scroll a few screens and switch the layout to the other one using radio buttons on the top. Scroll a bit so the recycler view produces a few more view holders and switch back to the first layout. After a few switch cycles the app will eventually crash with OutOfMemoryError. View holders's Dispose will never be called.
Doing the same with native app and you can see that view holder's finalizer method is called from time to time.
In the Android Studio profiler you can clearly see that native app is releasing memory from time to time and Xamarin app is not - memory is never released.
For me it means that Java GC is collecting unused objects whilst Xamarin app and Mono GC is not doing it. Calling GC periodically helps. This is obviously just a workaround but for me ot shows that GC is not called properly.

B. I've seen it on Samsung Galaxy A5 SM-A520F with Android 7.0 (API level 24); I've seen other devices listed on a few stackoverflow posts covering same issue. I believe this device (along with other listed) comes with custom android build. It introduces ios-like magnifier in text view which consumes a significant amount of memory (even if not used) hence the OutOfMemoryError pops up so quickly.

C. I'll prepare a Xamarin Profiler snapshot if still needed.
Comment 3 Michael Mazur 2017-12-18 14:29:16 UTC
I did not describe the issue in detail, so here it goes:
It's all about recyclerview's view holders that are not disposed properly when not needed anymore (although may apply to other scenarios as well).
So, the view holder is created when adapter requests one and Java should get rid of it when it's not needed anymore - that's what happens in native app.
In Xamarin however .net object for view holder is created which is bound to Java object. From that point on it is maintained by recycler view's adapter but since there's still .net object bound to it the GC cannot dispose it so the instance on both sides exists.
The problem is that there is no way to know which view holders can or should be disposed so the java object can be released too.
I reckon this should be handled by the GC then.