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.
Related
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) .
We have an application built in .Net 4.5(C#, Winforms) which only in one production environment goes to NOt Respondingstate intermittently for 10 to 20 second.
I have written log on important lines. It hangs on loading heavy user controls and when data fetching calls are done.
The system on which it hangs has considerably low memory 2GB. I have almost reproduced the situation on a local machine by lowering the memory. My question is what are my options to avoid these hangs up.
The application memory does raises 200 to 300 mb.
The behavior is not consistant. Some time it takes 30 seconds to complete a task the next time it takes 3 seconds hardly.
The Not responding state comes usually in the start up.
My last attempt was i loaded the important assemblies on start up but i have no luck.
Lastly let me tell you that we have several third party controls.
If you are concern about memory allocation,
Use the .NET Memory Allocation option of the Performance Wizard found in the Analyze menu to create a Performance Session which will help you figure out what changes you need to make in your code to reduce memory usage.
We really need more info here. But a few suggestions:
Use the using keyword or call Dispose() on all disposable objects when
you are done with them
Make sure you unregister event handlers when you are done listening
for events
If you have lot of timers in your application,
This is only a problem with the System.Threading.Timer class if you don't otherwise store a reference to it somewhere. It has several constructor overloads, the ones that take the state object are important. The CLR pays attention to that state object. As long as it is referenced somewhere, the CLR keeps the timer in its timer queue and the timer object won't get garbage collected. Most programmers will not use that state object, the MSDN article certainly doesn't explain its role.
System.Timers.Timer is a wrapper for the System.Threading.Timer class, making it easier to use. In particular, it will use that state object and keep a reference to it as long as the timer is enabled.
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.
I am fairly new to the .NET programming and I am currently developing a computer health monitoring system which is in its infant stage now. I will be using C# 2010 and querying computer information by using WMI queries.
Before I could further develop the application, I have created a mini test app to test out my classes and its methods. The flow of the test app is as follow:
App startup
Input hostname, username and password
Query button clicked and the querying methods fired.
A textfield on my UI gets updated, printing out the result of the queries.
I have a class called Machine, which contains properties such as the CPU Name, and some update-able properties like the current CPU usage. In that class, I have 2 main methods, GetStaticSysInfo and GetDynamicSysInfo, where the first method queries the system info that does not change over time, and the later one queries information like CPU and memory usage. I have another method named Refresh that I use to wrap around the GetDynamicSysInfo method.
As I am using WPF for my UI, I have used the DispatcherTimer to periodically queries the machine, and prints the updated info to the textfield on the UI after the Query button has been clicked. However, I noticed that each of the time I called machine.Refresh(), the memory usage of the app increases by a bit (few hundred KBs). I can't really figure out what's wrong with the program and I would appreciate that someone could provide some advices on this.
Please let me know if you need more information, or any portions of the code.
Thanks in advance.
EDIT: I have added a GC.Collect() on the Timer_Tick method, and it seems like the memory usage still climbs but it is lowered once every few timer ticks. It is still increasing, but at a slower rate. Is this the correct way of doing it and will it impair performance in the long run?
Except for diagnosis purposes you should never call GC.Collect(). The runtime has much better algorithms for when the GC should run. Also, calling Collect() too often can result in objects being promoted to 1st or 2nd generation, which actually means they are collected more slowly after they are not used anymore, i.e. increasing your memory footprint.
If the memory goes down again (to the previous value) after manually collecting, then you have no memory leak. Since the GC doesn't run all the time, you will have increased memory in between GC runs. That is no cause for concern.
I've been experiencing a high degree of flicker and UI lag in a small application I've developed to test a component that I've written for one of our applications. Because the flicker and lag was taking place during idle time (when there should--seriously--be nothing going on), I decided to do some investigating. I noticed a few threads in the Threads window that I wasn't aware of (not entirely unexpected), but what caught my eye was one of the threads was set to Highest priority. This thread exists at the time Main() is called, even before any of my code executes. I've discovered that this thread appears to be present in every .NET application I write, even console applications.
Being the daring soul that I am, I decided to freeze the thread and see what happened. The flickering did indeed stop, but I experienced some oddness when it came to doing database interaction (I'm using SQL CE 3.5 SP1). My thought was that this might be the thread that the database is actually running on, but considering it's started at the time the application loads (before any references to the DB) and is present in other, non-database applications, I'm inclined to believe this isn't the case.
Because this thread (like a few others) shows up with no data in the Location column and no Call Stack listed if I switch to it in the debugger while paused, I tried matching the StartAddress property through GetCurrentProcess().Threads for the corresponding thread, but it falls outside all of the currently loaded modules address ranges.
Does anyone have any idea what this thread is, or how I might find out?
Edit
After doing some digging, it looks like the StartAddress is in kernel32.dll (based upon nearby memory contents). This leads me to think that this is just the standard system function used to start the thread, according to this page, which basically puts me back at square one as far as determining where this thread actually comes from. This is further confirmed by the fact that ALL of the threads in this list have the same value for StartAddress, leading me to ask exactly what the purpose is...?
Edit 2
Process Explorer let me to an actually meaningful start address. It looks like it's mscorwks.dll!CreateApplicationContext+0xbbef. This dll is in %WINDOWS%\Microsoft.NET\Framework\v2.0.50, so it looks like it's clearly a runtime assembly. I'm still not sure why
it's Highest priority
it appears to be causing hiccups in my application
You could try using Sysinternals. Process Explorer let's you dig in pretty deep. Right click on the Process to access Properties. Then "Threads" tab. In there, you can see the thread's stack and module.
EDIT:
After asking around some, it seems that your "Highest" priority thread is the Finalizer thread that runs due to a garbage collection. I still don't have a good reason as to why it would constantly keep running. Maybe you have some funky object lifetime behavior going on in your process?
I'm not sure what this is, but if you turn on unmanaged debugging, and set up Visual Studio with the Windows symbol server, you might get some more clues.
Might be the Garbage Collector thread. I noticed it too when I was once investigating a finalizer-related bug. Perhaps your system memory is low and the GC is trying to collect all the time? This was the case in the previously mentioned bug too. I couldn't reproduce it on my machine, but a co-worker of mine had a machine with less RAM where it would reappear like clockwork.