February 12, 2016
After being let down by the failures Xamarin Forms we resorted to using Xamarin to write two native applications. Recently we become aware our application must have a pretty large memory leak and so needed to investigate the problem.
Xamarin have a profiler tool so it should be easy right?
Well after attempting to use it for a day and being unable to get a list of live memory objects or an up to date list of references to an object we contacted support.
Their response came back pretty quickly:
Snapshot breaking on Android is a known issue and one we are working with the runtime team to fix. Auto snapshots should work, but are not an ideal solution.
Ok, so the methods we were using weren’t quite working but if rather than having on demand snapshots we could work with ones that happen automatically.
Right? Nope, after a couple of frustrating hours we had managed to get the profiler capture one automatic snapshot and then freeze up / not capture any more.
This was getting rather problematic! But if we could change the time of the snapshots we could get far enough into the application to recreate the problem and investigate from there.
Nope! The snapshots were so unreliable that we could not change the snapshot time and get a reliable snapshot. Even when you did you couldn’t trust the result!
We couldn’t use the Xamarin tools. How about the normal Android ones. Although we wouldn’t be able to see all the objects - most business logic is handled exclusively in shared .net code - it should still give us a hand.
It was at this point we discovered our Android activities were not being released! Aha.. That’s a major problem! Time to actually solve something.
Oh wait, all those references to the activity look valid.. Hmmm.. What’s keeping them around?
Small sample project
As the project we’re working on is rather complex we stepped back and created a sample Xamarin Android app to test what was going on.
You can download that here
It’s an application that contains 3 activities:
- MainActivity - with a button to press that launches SecondActivity
- SecondActivity - with a button to press that launches ThirdActivity
- ThirdActivity - has a button to call finish.
Each time the activity is created it increments a class static variable which is then shown when the activity is onscreen.
With the Android device’s developer option set to close activities as soon as they are off screen we run a test.
The test consisted of opening the MainActivity, pressing the button and then moving between the SecondActivity & ThirdActivity 5 times.
The result was this screen.
Then looking at the result in the Android hprof viewer
Err, why have we got 3 activities in memory? Two should have been closed by the system already.
If we do the same with a pure native application, which you can download here, the activities are released as you’d expect.
This shows the problem is down to the use of Xamarin which is worrying.