Category Archives: Uncategorized

Memory Leak in Prism.Core (Xamarin.Forms)

Prism Version: 8.0.0.1909
Packages:
Prism.Unity.Forms
Prism.Forms
Prism.Core

A couple of weeks ago, we found a memory leak in one of our Xamarin Apps. Pages that get navigated to were still kept in memory, eventhough they have been removed from the NavigationStack. I tried to figure out why the pages are still being kept in memory, therefore I wrote a small program to recreate the issue (as usal I started out with the Prism Template for Xamarin Forms Apps):

  1. MainPage with MainPageViewModel – has a command to navigate to Page2 using Prism’s PageNavigationService
  2. Page2 (allocates 10MB data) and also has a ViewModel with 10MB memory allocation

Started the App, and navigated to Page2 – 9 times and back.

JetBrains dotMemory – first try

As you can see the memory consumption is going up all the time. When I trigger the Garbage Collector, some memory got freed.. But why? Easy as this – I didn’t bind the ViewModel to the View, so there was no retention path that holds the ViewModel back from being collected by the GC. The connection between the View and the ViewModel will be cut off by the Prism framework.

But what about the View – Why isn’t the View cleared from memory? Memory profiling is a little bit like searching a needle in the haystack. But JetBrains dotMemory is a great Tool and helps a lot. You can choose a specific instance, and you’ll find all objects that may be keeping it alive.

JetBrains dotMemory – Incoming References for Page2

Actually we would have to have a look at all of those references, one after the other. That’s very time consuming, and boring. But when we have closer look, we’ll see that Prism somehow looks very conspicious – the PageNavigationService, which implements INavigationService in Xamarin.Forms.

The reason why if has a reference to the page is, that it’s a PageNavigationService, that only works in connection to a specific page, so it isn’t strange that it keeps a reference to the page. But why is it still in memory? The only reference was used within the ViewModel, and that has been garbage collected. There has to be another reference, that’s why we need to have a look at the Prism Source Code, where the NavigationService is being created:

https://github.com/PrismLibrary/Prism/blob/master/src/Forms/Prism.Forms/Navigation/Xaml/Navigation.cs

public static class Navigation
{
        internal static readonly BindableProperty NavigationServiceProperty =
            BindableProperty.CreateAttached("NavigationService",
                typeof(INavigationService),
                typeof(Navigation),
                default(INavigationService));

        private static INavigationService CreateNavigationService(IScopedProvider scope, Page page)
        {
            var navService = scope.Resolve<INavigationService>();
            switch (navService)
            {
                case IPageAware pa when pa.Page is null:
                    pa.Page = page;
                    break;
                case IPageAware pa1 when pa1.Page != page:
                    return CreateNavigationService(ContainerLocator.Container.CreateScope(), page);
            }

            page.SetValue(NavigationScopeProperty, scope);
            scope.IsAttached = true;
            page.SetValue(NavigationServiceProperty, navService);

            return navService;
        }
}

I removed some lines of code, that are not imprtant. As you can see, the NavigationService is being attached to the page itself using an AttachedProperty. That’s a pretty cool solution, but the disadvantage is that AttachedProperties are nothing more than a big static Dictionary. The key of that Dictionary is the HashCode of the page (so this is a weak reference) and the value is the instance of the NavigationService (which in fact is being a static weak reference, including the BindingContext).

Update (2021/03/07) The reference of the attached property to the PageNavigationService actually is a (static) weak reference. Somehow the PageNavigationService is still bound, and the GC can’t free the memory.

A quick hack to solve that problem is to implement IDestructible within your PageViewModels (or ViewModelBase, when you use the Prism VS-template) and remove the Page-reference from the NavigationService:

public virtual void Destroy()
{
    if (NavigationService is IPageAware pageAware)
    {
        pageAware.Page = null;
    }
}

CSC : error CS1703: Multiple assemblies with equivalent identity have been imported (iOS)

I recently encountered a problem compiling my Xamarin.Forms iOS project. Everything worked well when testing the UWP App during development, but when I tried to test the iOS project, the compiler threw the following error:

CSC : error CS1703: Multiple assemblies with equivalent identity have been imported (iOS)'[..]\packages\system.reflection.emit\4.3.0\ref\netstandard1.1\System.Reflection.Emit.dll’ and ‘C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0\Facades\System.Reflection.Emit.dll’. Remove one of the duplicate references.

 
Checking those two files mentioned, you’ll find out, that those have two different versions (nuget cache: 4.3.0, VisualStudio: 4.0.0), also the path (and file size) states, that the file from the VisualStudio folder is only a facade.

The solution is quite simple, just add a package reference to your project-file excluding all assets:

&lt;PackageReference Include="System.Reflection.Emit" Version="4.3.0"&gt;
  &lt;ExcludeAssets&gt;all&lt;/ExcludeAssets&gt;
&lt;/PackageReference&gt;

.. just add it in an ItemGroup block with other package references and you solved that issue.

read and write properties on dynamic objects in .NET/C#

Ok, the headline sounds a little bit funny, because first of all, dynamic objects have no properties. Also you can not use reflection on a dynamic type, because it’s dynamic. What I actually want to do, is to access values of a dynamic object by its name – but I don’t know the name of the property on compile time, but during execution.

I want to do something like that:

dynamic obj = GetDynamicObject();
string myPropertyValue = DynamicExtension.GetValue(obj, "MyProperty");
DynamicExtension.SetValue(obj, "MyProperty", "some cool value");

So how can we do this? Reflection is not possible, and not all dynamic types impement IDictionary like ExpandoObject.

But how can we achieve this? By looking at the disassembled code, of a dynamic class, and the way it is accessed, we can find out, how we can access it ourself…

dynamic dynObj = new TestClass
{
  TestProperty = "Hello World",
  TestInt = 20
};
var val = dynObj.TestProperty;
dynObj.TestProperty = "Hello C#";

Because I don’t want to flood this post, I just copied the essentials from the IL. Basically there are 2 parts:
1. create a Binder
2. create a CallSite to execute the getter/setter.

// the getter
            var binder = Binder.GetMember(
                CSharpBinderFlags.None,
                "TestProperty",
                typeof(object),
                new CSharpArgumentInfo[] { 

 CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.NamedArgument, null)
                });

            var getter = CallSite&lt;Func&lt;CallSite,object,object&gt;&gt;.Create(binder);
            var val = getter.Target(getter,  dynObj);

// the setter
var setterBinder = Binder.SetMember(
    CSharpBinderFlags.None,
    "TestProperty",
    typeof(object),
    new CSharpArgumentInfo[] {
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) });
// the IL actually uses string as value type, but we use object here, to be more flexible
var setter = CallSite&lt;Func&lt;CallSite,object,object,object&gt;&gt;.Create(setterBinder);
setter.Target(setter, dynObj, "Hello C#");

So now just wrap it up to our two functions:

    public static class DynamicHelper
    {
        public static object GetValue(object obj, string name)
        {
            var binder = Binder.GetMember(
                        CSharpBinderFlags.None,
                        name,
                        typeof(object),
                        new CSharpArgumentInfo[] {
                            CSharpArgumentInfo.Create(
                                CSharpArgumentInfoFlags.NamedArgument,
                                null)
                        });

            var getter = CallSite&lt;Func&lt;CallSite,object,object&gt;&gt;.Create(binder);
            return getter.Target(getter, obj);
        }

        public static void SetValue(object obj, string name, object value)
        {
            var setterBinder = Binder.SetMember(
                CSharpBinderFlags.None,
                name,
                typeof(object),
                new CSharpArgumentInfo[] {
                  CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                  CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) });
            // the IL actually uses string as value type, but we use object here, to be more dynamic
            var setter = CallSite&lt;Func&lt;CallSite,object,object,object&gt;&gt;.Create(setterBinder);
            setter.Target(setter, obj, value);
        }
    }

Arduino Object-oriented

It has been more than a decade, that I switched over to programming in C# and even longer I am developing object-oriented code. But when it comes to Arduino, I can not count on C#. (Actually, there is an Arduino-like microcontroller, which can be programmed with C#. It is called Netduino) But we can still produce object-oriented code with Arduino.

Let’s first have a look at a simple Blink-App (from the Arduino tutorial).

// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

As you can see, there are two standard functions, that get called, when the code is deployed on the device. setup() when the device starts, and loop(), which is something like a while(true)-loop after the setup finished. The code does that, what it is meant to do, make a LED blink every second. But let’s assume we have a button, that shall turn the blinking on and off. My OOP-brain always keeps saying:

“There should be a LED-object and a Button-object”

I can imagine, that there are other solutions, but that was the first thing, that comes in mind when I think about it. So let’s draw something…

uml-buttonblinky.png

When we now come to the point to include those objects in the Standard setup-loop-pattern, we also need a loop and setup-function in each of the classes. These could be called from the main functions.

Here comes the code:

enum SwitchState
{
On,
Off
};
//---------- Light
class Light
{
SwitchState _currentState = Off;
byte _pin;

public:
Light(byte pin)
{
_pin = pin;
}
SwitchState GetCurrentState()
{
return _currentState;
}
// turns on the light
void TurnOn()
{
_currentState = On;
}

// turns off the light
void TurnOff()
{
_currentState = Off;
}

void Setup()
{
pinMode(_pin, OUTPUT);
}

void Loop()
{
if (_currentState == On)
{
digitalWrite(_pin, HIGH);
}
else
{
digitalWrite(_pin, LOW);
}
}
};
//---------- Button
class Button
{
SwitchState _currentState = Off;
byte _pin;

void OnSwitchChanged()
{
SwitchChangedEvent();
}

public:
void(* SwitchChangedEvent)();

Button(byte pin)
{
_pin = pin;
}

SwitchState GetCurrentState()
{
return _currentState;
}

void Setup()
{
pinMode(_pin, INPUT);
}

void Loop()
{
byte val = digitalRead(_pin);
if (val == HIGH &amp;&amp; _currentState == Off)
{
_currentState = On;
OnSwitchChanged();
}
else if (val == LOW &amp;&amp; _currentState == On)
{
_currentState = Off;
OnSwitchChanged();
}
}
};

//-------------------------- MAIN
Light led1(1);
Button button1(2);

void InvertLight()
{
if (led1.GetCurrentState()==Off)
{
led1.TurnOn();
}
else
{
led1.TurnOff();
}
}

void setup() {
led1.Setup();
button1.Setup();
button1.SwitchChangedEvent = InvertLight;
}

void loop() {
led1.Loop();
button1.Loop();
}

From this starting point, you can do a lot of fancy stuff. First of all, you could implement a base class, to actually wrap up those functions, that tend to produce code doubles. Also you may not want to trigger (and write) the digital pins on every loop. You can simply introduce something like a timestamp, skipping the loop for an amount of time. Everything can be made in a base class, so there will be no need to implement it every time again.