Timer increases memory usage in C# app - c#

I'm making a C# win form app (VS2010, .NET4) that uses a timer, my interval is 1s, I track task manager and it seems that my memory usage (the value written in front of app name in process tab of task manager) increases by each interval! I do nothing special in timer tick event, just increase an integer variable and display it in a label.
Is it normal? Should I be concerned about this memory problem? I'm going to run this program in my server (through remote desktop), would it cause any problems to my server? Would it run out of memory?
I use timer from VS toolbox.

Let's take the following example which updates a label every second with the current time:
var timer = new Timer
{
Interval = 1000,
};
timer.Tick += (s, evt) =>
{
label1.Text = DateTime.Now.ToLongTimeString();
};
timer.Start();
If you have code like this you shouldn't be worried about memory usage. The garbage collector could run at any time in order to free memory. It's just that you cannot determine when this happens.

Just for debugging, try forcing a garbage collection by running
GC.Collect();
Your memory usage should go back down to approximately where it was. By the way -- you can do this in the debugger by evaluating that expression in quick watch.

Related

Why is my application becoming less responsive over time?

I'm debugging a C# application that becomes almost unresponsive after a few days. The application calculates memory/CPU usage every second and displays it in the footer of the main UI.
The cause for the unresponsiveness is because of the time it takes to fetch the RawValue of a PerformanceCounter ("Working Set - Private"). After a couple of days, it takes almost a second to fetch the RawValue, freezing the main UI thread. If I restart my computer, everything is fast again for a few days until it slowly becomes less responsive. If I recompile this application without the PerformanceCounter code (it's open source), it runs normally immediately.
To rule out that it's the application, here's some sample code that does the exact same thing:
static void Main(string[] args)
{
using (var memoryWorkingSetCounter = new PerformanceCounter("Process", "Working Set - Private", Process.GetCurrentProcess().ProcessName, true))
{
while (!Console.KeyAvailable)
{
var memoryWorkingSetSw = new Stopwatch();
memoryWorkingSetSw.Start();
var memoryWorkingSetValue = memoryWorkingSetCounter.RawValue;
memoryWorkingSetSw.Stop();
Console.WriteLine(memoryWorkingSetValue.ToString());
Console.WriteLine(memoryWorkingSetSw.Elapsed.ToString());
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
Console.Read();
}
I left this running for ~2.5 days and graphed the Elapsed time in milliseconds:
What could cause a performance counter in Windows to become slow over time? Could another app be not cleaning it up? Is there a way to debug which apps are also looking at this performance counter? I'm on Windows 10.
why you declare Stopwatch inside a loop?
remove any new declaration possible inside loops.
when you do so the memory is increasing overtime and you count on garbage collector to do the work

WPF DispatcherTimer Memory Issue

Edit: If useful, this project is on GitHub at https://github.com/lostchopstik/BetterBlync
I am building an application for the Blync status light using their provided API. This application polls the Lync/Skype for Biz client and converts the status to the appropriate light color. All aspects thus far work as expected, however when I leave this program running for an extended period of time, the memory usage grows until a System.OutOfMemory exception occurs.
I have narrowed the problem down to the DispatcherTimer holding the timer in memory and preventing it from being GCed. After reading some things online I found you could manually call for garbage collection, but this is bad practice. Regardless, here is what I have in my code right now:
private void initTimer()
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan( 0, 0, 0, 0, 200 );
timer.Tick += new EventHandler( Timer_Tick );
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
// Check to see if any new lights are connected
blync.FindBlyncLights();
// Get current status from Lync client
lync.GetStatus();
// Change to new color
setStatusLight();
if ( count++ == 100 )
{
count = 0;
GC.Collect();
}
}
The timer ticks every 200ms. I commented out all methods inside the timer and just let it run empty, and it still burned memory.
I am wondering what the proper way to handle this timer is. I've used the DispatcherTimer in the past and not had this issue.
I would also be open to trying something besides the DispatcherTimer.
If it is also useful, I have been messing with MemProfiler and here as my current graph with manual GC:
http://imgur.com/Iut91mF
It's a little hard to tell without seeing the rest of the code or the class the timer belongs to. I don't see anywhere you call Stop() on the timer. Does it need to be stopped?
You could also keep a local reference to the timer in whatever class you're in and call Start() and Stop() as needed.
If the timer never needs to be stopped and runs indefinitely, I would certainly look at what you're allocating as the timer runs and that's probably where your issue is.

UWP Windows 10 App memory increasing on navigation

I have a UWP Windows 10 App and noticed the memory usage in task manager is increasing over time.
I stripped the App back and found the memory is increasing when the navigating pages. So I made a simple app with just a few pages to test and the memory is still increasing in this simple App. I have a MainPage that navigates a frame from Page1 to Page2 and back on a timer.
public sealed partial class MainPage : Page
{
private DispatcherTimer _timer;
private bool _page1Showing;
private bool _timerRunning;
public MainPage()
{
this.InitializeComponent();
_timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
_timer.Tick += _timer_Tick;
}
private void _timer_Tick(object sender, object e)
{
GC.Collect();
this.rootFrame.BackStack.Clear();
this.rootFrame.ForwardStack.Clear();
if (_page1Showing)
{
this.rootFrame.Navigate(typeof(Page2));
_page1Showing = false;
}
else
{
this.rootFrame.Navigate(typeof(Page1));
_page1Showing = true;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_timerRunning)
{
_timer.Stop();
_timerRunning = false;
}
else
{
_timer.Start();
_timerRunning = true;
}
}
}
Page1 and Page2 are empty pages with a grid with a background color so you can see the navigation. While this App runs the memory usage in task manager increases by around 1MB every 30 mins.
I have run the App using the memory diagnostics in VS2015 the Managed heap is as expected:
The heap is always increasing:
Comparing snapshots of the Heap shows:
I am confused what these McgInterop objects are? and why such a simple App is always increasing in memory usage. My main App needs to run for a long time (months+). Appreciate any help.
I have tried changing the pages NavigationCacheMode, if set to Required the pages are created once. If set to disabled the Pages are created every time, and I checked the finalizer is called as expected.
--
Edit: I added a button to start and stop the timer (updated the above). It seems that while the timer is running the memory usage in Task manager will increase, when the timer is stopped the memory usage eventually drops.
I measured the memory usage in task manager over a day starting and stopping the timer around every 2 hours as follows, it slowly increases and then drops at some point:
12.5 -> 17.1 -> 16.7 -> 13.9 -> 16.8 -> 22.5 -> 13.6 -> 14.6 -> 24.9 -> 15.2
So I guess everything is working fine? But I am not clear what is happening here, why is it increasing so much? When is it being free'd under what conditions?
Is the system delaying releasing memory while pages are navigating? when the user would normally be interacting with the screen?
Every time you navigate to a Page, you create a new instance of Page, but the previous Page is not disposed (even if the Page is already in the navigation stack).
To prevent multiple allocation of same page, set NavigationCacheMode="Enabled" attribute to the Page.
Also, to minimize the memory allocation, you must override method OnNavigatedTo and OnNavigatedFrom.
In OnNavigatedTo method:
Instantiate all memory intensive object or resources
Add all events handlers you need
starts all timers, tasks or threads
In OnNavigatedFrom:
Dispose all resources
Stops all timers, tasks or threads
Remove references from all heavy objects
Remove all events handlers
Only if you really need, call GC.Collect()
Can we see your xaml code? Are you using x:name in your xaml and is that being destroyed? If so that might cause your memory leak.
Look at this link if you are using x:name:
http://support.scichart.com/index.php?/News/NewsItem/View/21/wpf-xname-memory-leak--how-to-clear-memory-in-scichart
Of course a UWP may handle x:name differently...
I have seen the same problem on w8.1 with printingInline using charmBar it's consuming a lot of memory until crash of the application (1.5 GB). but normaly you don't need GC.colect() it's work automaticly .

How do I fire an event every 20ms *on average*? Inbuilt timer "creeps"

I'm writing an RTP server to publish PCMA wave files. It needs to pump data every 20ms (on average - it can be a bit either side of that for any 1 pump, but must average out at 20ms).
My current implementation uses a Timer, but then the event fires just over every 20 ms, so it gradually drifts out.
Is there a better way to do this? The only way I can currently think of is to dynamically adjust the timer inteval as it starts to creep, in order to bring it back in line.
Sample Code
void Main()
{
System.Timers.Timer timer = new System.Timers.Timer();
// Use a stopwatch to measure the "wall-clock" elapsed time.
Stopwatch sw = new Stopwatch();
sw.Start();
timer.Elapsed += (sender, args) =>
{
Console.WriteLine(sw.ElapsedMilliseconds);
// Simulate doing some work here -
// in real life this would be pumping data via UDP.
Thread.Sleep(300);
};
timer.AutoReset = true;
// I'm using an interval of 1 second here as it better
// illustrates the problem
timer.Interval = 1000;
timer.Start();
}
Output:
1002
2001
3002
4003
5003
6005
7006
8007
9007
10017
11018
12019
13019
14020 <-- By this point we have creeped over 20 ms in just 14 iterations :(
First of all: I will never get it to be exact because your program will never be in full control of what the CPU's are doing as long as you are running on standard Windows because it is not a real-time OS. Just think of a anti virus kicking in, the Garbage Collector freezing your thread, playing a game on the side, ...
That said you might be able to compensate a bit.
When the handler kicks in, pause the timer, record the current time, act, update the time's interval by setting the interval to the required interval based upon the start of the handler and the time it has taken to act.
This way you can control the creeping better. An exception to that might be when the acting takes longer than the interval and whether the interval should contain the time to act or be the time between to acts.
In my experience you cannot rely on any timer to get an interval that small (20 ms) accurately but compensating for creep can help quite a bit.
You could use StopWatch to measure time, but it doesn't have callbacks.
You can use Windows multimedia timer. It involves some WinAPI, but all the details are provided in this article.

Limiting user processor time and peek virtual memory with Job Objects

I'm writing an application runner on Windows which can limit processor user time and virtual memory for the application it will run. Idea is to have following:
runner.exe mem_limit_in_MB time_limit_in_sec command.exe command_arguments ...
My investigation lead me to Windows Job Objects API and since I'm trying to do all that from C#, I found JobObjectWrapper to help me.
The main part of the code if following:
using (JobObject jo = new JobObject())
{
// Time
jo.Limits.PerProcessUserTimeLimit = TimeSpan.FromMilliseconds(limitTime);
jo.Events.OnEndOfProcessTime += new jobEventHandler<EndOfProcessTimeEventArgs>(Events_OnEndOfProcessTime);
// Memory
jo.Limits.ProcessMemoryLimit = new IntPtr(limitMemory);
jo.Events.OnProcessMemoryLimit += new jobEventHandler<ProcessMemoryLimitEventArgs>(Events_OnProcessMemoryLimit);
// Process
ProcessStartInfo psi = new ProcessStartInfo(command, arguments);
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
jo.Limits.IsChildProcessBreakAway = false;
Process p = jo.CreateProcessSecured(psi);
p.WaitForExit();
}
Now, the problem is that it seams that Events_OnEndOfProcessTime is not called timely. If I set 0.5 sec limit for an app that takes several minutes, depending on the run application is once terminated after 0.5 sec and sometimes after 4 sec. Why is this happening? I cannot find any reference if Job Objects are checking limits periodically or in real-time.
My question is two-fold:
- Does anyone know about already developed code that does what I need?
- Does anyone know if Job Objects are executed periodically or in real time?
Thanks in advance...
PerProcessUserTimeLimit specifies the amount of user-mode time is granted to the process.
"The system periodically checks to determine whether each process associated with the job has accumulated more user-mode time than the set limit. If it has, the process is terminated." (MSDN)
Consequently it depends on your application, particulary on how effient it is burning user-mode time. Ending a process with PerProcessUserTimeLimit = 0.5 after 0.5 sec. means that it has used ~100% cpu (user-mode) during that time.
... if Job Objects are executed periodically or in real time? Periodically, as stated above.

Categories