UWP Windows 10 App memory increasing on navigation - c#

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 .

Related

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.

How to get timer running even when application is running in background or phone is locked in Windows Phone

I have a timer in my application in Windows Phone 7.1 implemented using
DispatcherTimer _timer;
Initialized as
Sample._timer = new DispatcherTimer();
Sample._timer.Interval = new TimeSpan(0, 0, 1);
Sample._timer.Tick += new EventHandler(Timer_Tick);
Sample._timer.Start();
private void Timer_Tick(object sender, EventArgs e)
{
double newValue = Sample.Value + 1.686;
if (newValue >= 100)
newValue = 0;
Sample.Value = newValue;
txtDigitalClock.Text = GetTime();
}
public string GetTime()
{
time += TimeSpan.FromSeconds(1);
return string.Format("{0:D2}:{1:D2}:{2:D2}", time.Hours, time.Minutes, time.Seconds);
}
This is working fine in normal condition
Here is my problem
1) Timer is not running when phone is in locked state(screen is loced)
2) Timer is not running when application is running in background (When you press start button in windows phone the app goes to background).
any help would be greatly appreciated..
To run your App (and Timer) under lock screen, you have to disable ApplicationIdleDetectionMode.
If you don't disable idle your App will stop as it is said at MSDN:
This event (Deactivation) is also raised if the device’s lock screen is engaged, unless application idle detection is disabled.
If you want to run Timer in the background (eg. after pressing Start buton), you won't be able to do this as MSDN says:
When the user navigates forward, away from an app, after the Deactivated event is raised, the operating system will attempt to put the app into a dormant state. In this state, all of the application’s threads are stopped and no processing takes place, but the application remains intact in memory.
The bigger problem is when your App is tombstoned - the app doesn't ramain (all) in memory.
You can try to do your job with Background Agents, but that is other story.
Also remember about Certification requirements when your App disables Idle or uses Background Agent.
Similar problem was here.
I searched for your question on google (cuz I'm not into Winphone) and found
http://stackoverflow.com/questions/8352515/how-can-i-run-my-windows-phone-application-in-background
apparently it simply is not possible.
I hope this answers your question
Please write below line timer Initialization
ApplicationIdleModeHelper.Current.HasUserAgreedToRunUnderLock = true;
I resolved this issue by saving the starting timer of the value on isolated storage
IsolatedStorageSettings.ApplicationSettings.Add("TimerStarted",DateTime.UtcNow);
And when the app is reactivated after going to background, i will look for this value in isolated storage and use that to show the timer

Timer increases memory usage in C# app

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.

Windows Phone 7 Multiple Sounds Lag

I'm making a drum machine. From what I've read, it looks like the XNA SoundEffect class runs based on a timer, which causes a noticeable lag, and stops the rhythm being smooth.
I tried to use MediaElement, 'til I found out you cannot play multiple sounds at the same time.
Are there any workarounds for this? The sounds are handled by a timer, and need to play instantly.
I've done some in-game use of the XNA SoundEffect class and not seen any lag when responding to user events - e.g. button presses - especially when the sound effect is pre-loaded from resources.
The XNA class is designed to be used for sound effects - so it should be ideal for a single drum machine hit.
If you then see problems with timing on IsLooping, then I guess you'll have to implement your own timer to trigger new instances - but my advice would be to try it first.
Hope that helps
I've been using some sound in my app and I used the code from the example given on the msdn code samples website: http://msdn.microsoft.com/en-us/library/ff431744(v=vs.92).aspx
It looks like they are updating the timer every 50ms. Also note that the SoundEffect variables (coyoteSound and birdSound) are private data members where they only load once. The event handler on the button clicks simply call SoundEffect.play().
public MainPage()
{
InitializeComponent();
LoadSound("Resources/NightAmbientCreatureOneShot_01.wav", out coyoteSound);
LoadSound("Resources/AfternoonAmbientBirdOneShot_09.wav", out birdSound);
LoadSoundInstance("Resources/NightAmbienceSimple_01.wav", out ambienceSound, out ambienceInstance);
// Set the volume a little lower than full so it becomes the background.
ambienceInstance.Volume = 0.8f;
// Turn on looping so it runs continually in the background.
ambienceInstance.IsLooped = true;
// Timer to simulate the XNA game loop (SoundEffect classes are from the XNA Framework)
DispatcherTimer XnaDispatchTimer = new DispatcherTimer();
XnaDispatchTimer.Interval = TimeSpan.FromMilliseconds(50);
// Call FrameworkDispatcher.Update to update the XNA Framework internals.
XnaDispatchTimer.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
// Start the DispatchTimer running.
XnaDispatchTimer.Start();
}

Why is this code consuming more and more ram?

public partial class Form1 : Form
{
bool AfterDocumentCompleted = false;
int steps = 0;
public Form1()
{
InitializeComponent();
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocCompletedHandlerCopy);
webBrowser1.ScriptErrorsSuppressed = true;
}
private void DocCompletedHandlerCopy(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete && e.Url == webBrowser1.Url)
{
AfterDocumentCompleted = true;
}
}
private void NavigateAndWait(string urlString)
{
AfterDocumentCompleted = false;
webBrowser1.Navigate(urlString);
while (AfterDocumentCompleted == false) Application.DoEvents();
steps += 1;
label1.Text = string.Format("{0:00000} / {1}MB", steps, Environment.WorkingSet / (1024 * 1024));
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
NavigateAndWait("http://www.crucial.com/");
NavigateAndWait("http://www.google.com/");
NavigateAndWait("http://www.microsoft.com/");
NavigateAndWait("http://www.stackoverflow.com/");
NavigateAndWait("http://www.yahoo.com/");
}
}
}
When I click Button1 (so it calls button1_Click) and wait for about 1 hr, the ram consumed according to Task Manager and label1 is about 1000MB (is about 20MB as soon as I click it and the rate of grow is somewhat linear). Is the WebBrowser some kind of alpha version of a browser that is not supposed to be used at all by anyone, or am I doing something wrong. If you wonder why in the world do I want to navigate for ever to those pages, this is just the isolation of a problem I was having (see my other question here).
Edit: About a week ago I installed and uninstalled IE9 beta. I think that might have originated the problem. Just tested it on a Windows Vista IE8 and it didn't grow any bigger than 80-90MB. I'll just reinstall Windows and I hope I don't need to downgrade to Windows Vista.
Edit2: I finally found the cause of the problem. It was not IE9 beta. It was the fact that I set IE not to show any pictures. I thought not showing pictures would make navigation faster and lighter, but apparently it activated some bug and the memory consumed started growing like crazy. Still, with pictures the memory grows but a lot slower.
and wait for about 10 minutes, the ram consumed according to Task Manager is about 200MB
200 MB is not a lot
TaskManager is not suitable for measuring memory use
The WebBrowser you use through the control is IE. It will consume quite a bit of memory, mostly to cache content. But you don't really have a problem with memory.
Additional:
I ran your App and changed only this method (add Label1) :
int counter = 0;
private void NavigateAndWait(string urlString)
{
AfterDocumentCompleted = false;
webBrowser1.Navigate(urlString);
while (AfterDocumentCompleted == false) Application.DoEvents();
counter += 1;
label1.Text = string.Format("{0:000} {1}", counter,
Environment.WorkingSet/ (1024*1024));
}
When I let it run for a while Memory stabilizes at a 75-85 MB range.
In a comment you mention 1.6 GB, that is a problem. But that was not with this code. So you have a start: look for the differences.
Edit 2
Upgrade your version of IE. I am running this with Vista/32 and IE8 and the WorkingSet won't go over 90MB. (600 pages)
or am I doing something wrong
Well, this is not going to be a good idea:
while (AfterDocumentCompleted == false) Application.DoEvents();
You're introducing reentrancy and a tight loop in the high priority UI thread. I don't know to what extent that will hamper the garbage collector, but I wouldn't be surprised if it did. Basically you're abusing the UI thread, which is bound to cause oddities. (As Henk says, 200MB in 10 minutes isn't exactly a runaway resource leak anyway.)
This just isn't a good idea. "Isolating" a problem by adding code like this isn't going to help.
You already have a DocumentCompleted handler... why not use that to navigate to the next page, instead of this tight loop?
I'm not sure why it would be unclear why you are using lots of memory; you are reloading web pages over and over again endlessly. Right now my browser is using 140megs of memory, and I'm not reloading pages constantly.

Categories