Why don't people use object pooling in Xamarin? - c#

I'm new to mobile development, and by extension, Xamarin. One thing I've always noticed is that any time a page is loaded, people always request to make a new page() as opposed to have a pool or set list of pages they can access.
Won't this cause memory problems? Does Xamarin automatically remove older pages from the scope? Sorry if it sounds like a dumb question, but it's something that threw me off as my first instinct as a programmer is usually to limit unnecessary repeats of data in the memory.

Xamarin is .NET based technology and as such memory management is based on the garbage collection. As such if you follow good practices your generated page that is not needed anymore should be garbage collected at some point.

This is a good question. If you are having a memory leak on the page navigation, you can look at this document first.
The NavigationPage class provides a hierarchical navigation experience where the user is able to navigate through pages, forwards and backwards, as desired. The class implements navigation as a last-in, first-out (LIFO) stack of Page objects.
So you can see that all the pages are on the stack when you are navigating the page. Simply put, xamarin handles their memory release internally as the stack is pushed.
If you are still concerned about memory leaks, you can refer to Xamarin.Forms App Lifecycle to manually release objects based on the end of the page's life cycle.
About Explicit call to garbage collector on navigation back in the stack
This one is a controversial one. Some people say that you should never explicitely call to garbage collector. And, in general, I would agree with this. However, in Xamarin the magic call to GC.Collect() can do wanders. If nothing else helps, just call to GC.Collect(); immidiately after calling await _navigation.PopAsync(true) .

Related

How can I view the async stack traces while debugging a .NET application in Visual Studio?

I am trying to figure out the cause of a (possible) memory leak in a complex C# based application. As I cannot debug the problem at runtime due to the system becoming very slow and unstable because of the high CPU and memory usage of the application, I created a dump (dmp) file of the application via the task manager at runtime and then opened that dump for further analysis in my local Visual Studio 2022 instance. When I now try to view the threads of the application at the point of time when the dump was created, it only shows me the call stack until where something async is executed. Everything that happens inside this async execution seems impossible to access. In the call stack it just says that it is waiting for an async process and I should double click or press enter to show async call stacks. However, this doesn't seem to do anything. Am I missing something, or how can I see what is happening inside the async process?
The typical approach to find memory leaks would be to create two or more memory snapshots/dumps and compare them with a memory debugger to see if there is some type of object that seem to only increase in count. I'm not sure stack traces would provide all that much value when trying to find memory leaks.
I have mostly used dotMemory but have no affiliation. I would expect most competent tools to have equivalent functionality, but terminology might be different.
There should be a comparison view where you should be able to sort object by either delta count or delta bytes . This often provides a good indication on what objects are leaking.
Once you have a candidate type you should be able to inspect an instance of that type and some way to view a retention graph where you can view the graph of objects keeping your instance alive. If you see anything suspicious, you should review the code and see if there is some possibility for leaks.
Common reasons are unregistered event handlers. If a object registers an event handler it should also ensure it is unregistered. If it is done in the constructor you should implement IDisposable and unregister in the dispose method, and ensure the object is always disposed. Possibly with a finalizer that only runs for undisposed objects, that logs, or otherwise alerts you, that the object was not disposed.

Navigation of pages and running in the background

In UWP (XAML / C#) I use Frame.Navigate(typeof(Page2));, and in C# of Page2 I use timer and when I use Frame.GoBack();, the frame really goes back, but the timer is not stopped - I mean the page and all its components are still running in the background, and the app is consuming too much RAM because of that. How can I "kill" the page?
note: if user uses this navigation 10 times, the page is 10 times in the background and it is bad..
It is important to understand that CLR garbage collector is the one who is responsible for "killing" unused objects. An object (and all of it's members) becomes "unused" when it is no longer referenced.
When you start a Windows.UI.Xaml.DispatcherTimer, it adds itself to a timer collection inside the current Dispatcher, thus, creating a direct reference between the Dispatcher and the timer. The timer, in its turn, holds a reference to the page where it is running. Since the Dispatcher is a global object, it will keep your page alive until the timer is stopped.
There can be other causes of memory leak (it is a pretty broad topic), including:
Other sources of direct or indirect references to your page;
Subscriptions to static events;
Complex data bindings like {Binding Path=Property.Subproperty};
I would suggest you to use a memory profiler to find memory leaks if the above doesn't help, such as the Diagnostic Tools included in Visual Studio 2015.

Memory Management Ideas?

I'm writing a game in C# with SharpDX...
So, for drawing a frame, currently i'm using a Timer, with interval set to 1;
But this is too slow for a game, so i want something faster...
First of all, if I use another thread for the game (and another for the Window itself) and i use a "[while (InGame)]" statement, it is fast, but the GC will never release a single object, and the memory usage just going up and up...
IF I use the SharpDX built in "RenderLoop" function, it is fast also, but the GC still doesn't do anything...
I've tried to override the Window form "WndProc" function, but the game only refresh itself then i'm moving the mouse like a crazy men...
This is my first real game, with a lot of functions,
so if any of you have any idea, how would i fix it, or what should I use, I would appreciate it...
There must be something in the Window Form lifecycle like a
void FormLife
{
WndProc();
HandleEvents();
etc...
}
(It was just a hard example...)
OR how can i force the GC to do its job, at the end of the while(InGame) state ?
I've tried GC.Collect(); but its dont work...
Don't put your game logic in the UI classes.
Use a multimedia timer and a dispatcher to return to main thread for rendering. From my experience a cycle of 5mSec works well. (Lower will waste CPU time).
Use dispatcher priority of Input so that the timer won't choke the UI and prevent it handling user events.
On timer event, if the previous update hasn't completed, return immediately without doing anything (you can use System.Threading.Interlocked.CompareAndExchange as a cheap sync method).
To make game run faster, try to reuse objects and change their states or to pass short living immutables so that the GC won't delay your program.
Use the IDisposable pattern where applicable.
If GC.Collect does not free memory you have a memory leak. Use the memory profiling tool of your choice to spot the leak (PerfView, Windbg, .NET Memory Profiler, YourKit, ....)
Besides this the best allocation is no allocation at all. If you reuse objects and keep unused objects in a pool you can get rid of GCs almost entirely. Even if you stay away from Gen 2 collections which can block your game for hundreds of ms you also need to keep a sharp eye on Gen 0/1 collections which can also cause noticeable delays.
See http://social.msdn.microsoft.com/Forums/vstudio/en-US/74631e98-fd8b-4098-8306-8d1031e912a4/gc-still-pauses-whole-app-under-sustainedlowlatency-latencymode-despite-it-consumes-025gb-and?forum=clr
You don't typically have to worry about memory management. If you are making sure not to hold on to references then the garbage collector should do its thing automatically based on memory pressure.
You can force it yourself using GC.Collect but you need to be absolutely certain you really need to. Most of the time its not required. Check this thread for more info and points to consider: Best Practice for Forcing Garbage Collection in C#
Since the objects are not being collected you must be holding a reference to them somewhere.
You didn't post much code so it is hard to say where you are holding a reference.
In the past I've used windbg to find the root cause of of memory issues. VS2013 has a memory profiler built in (might be easier to use).
A common case I've seen of holding references is via event subscription. If you have subscribed to any events you have to make sure you unsubscribe to release the object. see Why and How to avoid Event Handler memory leaks? for more details. That doesn't look like your problem.

Silverlight InitializeComponent

Are silverlight pages initialized every time they are called? InitializeComponent();
Once they are called is this stored in memory?
If they are Initiallzed everytime they are called is there a way to check to see if it has already been rendered so as to bypass the rendering of the page?
A page is an object like any other - if you create one, then navigate to a different page, the original is no longer referenced and becomes eligible for garbage collection. If you visit the page again, you get an all-new instance.
You asked this question in terms of a preconceived solution (avoid page rendering). What is the underlying issue that led you to consider this approach?

Object relationships

This stems from a recent couple of posts I've made on events and memory management in general. I'm making a new question as I don't think the software I'm using has anything to do with the overall problem and I'm trying to understand a little more about how to properly manage things. This is ASP.NET.
I've been trying to understand the needs for Dispose/Finalize over the past few days and believe that I've got to a stage where I'm pretty happy with when I should/shouldn't implement the Dispose/Finalize. 'If I have members that implement IDisposable, put explicit calls to their dispose in my dispose method' seems to be my understanding. So, now I'm thinking maybe my understanding of object lifetimes and what holds on to what is just wrong!
Rather than come up with some sample code that I think will illustrate my point, I'm going to describe as best I can actual code and see if someone can talk me through it.
So, I have a repository class, in it I have a DataContext that I create when the repository is created. I implement IDisposable, and when my calling object is done, I call Dispose on my repository and explicitly call DataContext.Dispose( ). Now, one of the methods of this class creates and returns a list of objects that's handed back to my front end.
Front End -> Controller -> Repository -> Controller -> Front End.
(Using Redgate Memory Profiler, I take a snapshot of my software when the page is first loaded). My front end creates a controller object on page load and then makes a request to the repository sending back a list of items. When the page is finished loading, I call Dispose on the controller which in turn calls dispose on the context. In my mind, that should mean that my connection is closed and that I have no instances of my controller class. If I then refresh the page, it jumps to two 'Live' instances of the controller class. If I look at the object retention graph, the objects I created in my call to the list are being held onto ultimately by what looks like Linq.
The controller/repository aside, if I create a list of objects somewhere, or I create an object and return it somewhere, am I safe to just assume that .NET will eventually come and clean things up for me or is there a best practice? The 'Live' instances suggest to me that these are still in memory and active objects, the fact that RMP apparently forces GC doesn't mean anything?
If the objects are no longer rooted, they will eventually get removed from memory altogether, but calling Dispose will not cause the object to be completely removed from memory right away. The Dispose merely allows you to clean up unmanaged resources, and resources that need to be freed up asap.
In other words: your connection should be closed, but there will still be a "disposed" DataContext instance in memory.
You might want to read this article about .NET garbage collection.
My answer to your your questions consists of 2 parts:
As an application developer, you would never need to perform GC yourself. That is up to .NET. In the Dispose() method, you would only be required to relinquish or free resources that you have acquired, but not required calling any method to do garbage collection explicitly. If you do, at best, when it's done is undeterministic.
When your controller returns a list to the front end, remember that the front end does not need to know nothing about what your server-side (backend) technology is. It could be C#, Java, PHP, you get the idea. The response the backend returns to the front end is just an HTTP response, and complies to the HTTP protocol. So once the response is framed and returned to the frontend, the controller method goes out of scope, the objects in that scope are up for garbage collected. You won't have to worry about memory leaks in that situation.

Categories

Resources