Skip to content Skip to sidebar Skip to footer

Xamarin Android Garbage Collection Algorithm

I am reading the Xamarin.Android garbage collection docs about helping the GC perform better by reducing referenced instances. The section begins by saying: Whenever an instance o

Solution 1:

I'll try to explain this the best I can, and I'm nowhere near an expert here so anyone who wants to chime in, please do so.

When we are referring to doing a peer walk, we are locating any roots and traversing the live reference graph to see what is reachable and what is not:

enter image description here

Root Objects:

  • Objects pointed at by static fields / properties
  • Objects on the stack of each managed thread
  • Objects that have been passed into native APIs

Basically you then have to deal with two managed GCs. We'll call them the Xamarin GC and the Android GC for reference.

enter image description here

Xamarin.Android has peer objects which are used to reference the native Java objects known in the Android JVM. They implement a core interface:

namespaceAndroid.Runtime
{
    publicinterfaceIJavaObject : IDisposable
    {
        // JNI reference to the Java object it is wrapping. // Also known as a pointer to the JVM objectpublic IntPtr Handle { get; set; }
        ...
    }
}

Whenever we have an object with IJavaObject inherited, it will keep a strong reference via that JNI handle above to ensure it is kept alive as long as the managed object is alive.

Think of it this way:

IJavaObject -> IntPtr Handle -> Java Object

In GC terms, it would be represented as the following:

Allocated and collected by Xamarin GC -> GC Root -> Allocated and collected by Android GC

We then have a GC process in Xamarin.Android:

enter image description here

When the GC runs, you can see that it will replace a strong JNI handle with a weak reference and then invoke the Android GC which will collect our Java object. Because of this, the peers are scanned for any relationships to ensure that they are mirrored in the JVM. This keeps these objects from being collected prematurely.

Once this happens, we run the Android GC and when it's finished it will walk through the peer objects and check the weak references.

  • If an object is gone, we collect it on the C# side
  • If an object still exists, then we change the weak reference back to a strong JNI handle

Thus this graph needs to be checked and updated each time a GC runs on peer objects. That's why it's much slower for these wrapper type objects because the entire object graph has to be scanned starting at the peer object.

So when there are significant object graphs that our peer object uses, we can help out the GC process by moving the storage of the references outside the peer class. This is usually done by rooting our reference independent of the peer. And since it's not stored as a field, the GC will not try to do a relationship walk on the object graph.

As noted earlier, this isn't a huge issue to worry about until you notice long GCs. You can then use this as a solution.

Image Credit: Xamarin University(https://www.xamarin.com/university)

Post a Comment for "Xamarin Android Garbage Collection Algorithm"