I'm pretty new to Xamarin development and having been trying to trace what I think are memory leaks in an existing, complex project I decided this morning to check what happens to memory use in a very simple project. I fired up a new Xamarin forms application and built a project with two forms MainFom simply has a button to check current memory usage and a button to open the child form. ChildForm has an image (called ImageDisplay) that's loaded with a URL when the form's constructed and a button to return to the MainForm. Here's some code from the ChildForm:
public partial class ChildPage : ContentPage {
public ChildPage() {
InitializeComponent();
// Add a parameter to make the URL unique to ensure it's loaded fresh each time
String url = "**Image URL**" + Environment.TickCount.ToString();
Console.WriteLine("Fetching: " + url);
ImageDisplay.Source = ImageSource.FromUri(new Uri(url));
}
async void BackToMainForm(object Sender, EventArgs e) {
// Remove self from the navigation stack
await Navigation.PopAsync();
GC.Collect();
Console.WriteLine("Application is using " + ((int)(GC.GetTotalMemory(false) / 1024)).ToString() + "k of memory.");
}
}
All looks pretty simple. However when I run the application and switch back and forth between the two forms, the memory usage creeps up, generally by a few kilobytes, sometimes jumping up or down by 20k or so, but generally creeping ever higher. This happens both on Android (where the memory use starts out around 4MB) and on iOS (where memory use starts around the 7-800kB mark). There's nothing else that I've written in the solution that is tracking objects or holding onto references to them. So my questions:
1. Is this a bug? Either in my code, in Xamarin or, indeed in something deeper. I'm quite happy to accept that it's normal for memory to be being used holding onto diagnostic information, application output or whatever as the application runs, but with so many discussions of memory leaks, I'm not sure whether the simple code above has a leak or is running normally, if it's normal to accept memory creeping higher, how much should I accept - my more complex project has up to 1-200kB more use after switching page and back.
2. Is it a problem? Whether or not it's a bug, does this memory use mean that things will run out of memory? Obviously it's going to take a long time to use all the memory in a modern smartphone 1kB at a time. If it is indeed normal for diagnostic information to be taking up memory, will it be freed once memory becomes scarce? Is it just garbage collection being lazy when there is plenty of memory free and once it isn't things will be reclaimed?
3. Is there anything I can do about it? If this is a problem, how can I fix or at least mitigate against it? I would expect a modern language like C# to deal with the disposal of objects automatically, but do I need to be explicitly tearing down each of my forms rather than just popping them from the navigation stack? Should I be setting (or at least aware of) memory limits on holding application output / diagnostic traces? Am I worrying over nothing?
Things I've tried to see if I can stop the memory usage creeping up:
- Using a release rather than debug build.
- Explicitly setting ImageDisplay.source to null when finished with the ChildForm
- Not loading the child form, just periodically displaying memory use from a button - much slower, but memory still creeps up by 1kB every few minutes.
- Not having the image on the child form, just switching between forms
Thanks in advance.
Note, apparently I'm too new a user to have a URL in my post incase it's a spam link, the images are coming from a placeholder service and are 500x500 pixels.