Hi
currently I'm building the application that perform some kind of monitoring.
For displaying the information I'm using all kinds of RadGauge (i.e. Circular, Linear, Digital).
All is fine and the controls look amazing, however I have found that the application has a memory problem
(i.e. more time the application is running - more memory it has been using). The application doesn't use any kind of saving the history, I mean that it is just Real Time Monitoring - thats why there shouldn't be increasing memory size used by the application.
In general the application architecture is very simple and as I have found later it is quite similar to those you are using in the demo example (i.e. CarDashboard Gauge WPF example).
So, in general I have an object that has a list of monitoring properties, the object itself derived from INotifyPropertyChanged interface to be able to reflect the UI elements(i.e. gauges that are binded to those properties - simple binding) and DispathcherTimer which update the properties values with some interval.
I have used the .Net Memory Profiler to determine the reason of memory increasing and found that the problem in Resources that RadGauges used - they are not releasing. There are different kind of resources, for example objects like
System.Windows.Media.Animation.Clock.RootData
System.Windows.Media.Animation.Clock.SubtreeFinalizer
System.Windows.Media.Animation.AnimationClock
and many others. In the period of 20 min with the update interval set to 1 sec I have from 4 to 2 thousand new instances of each of those types have been created and haven't been removed. And here is the place where the memory of my application is increased.
If we would check the Call Stack of each of those object types we would found very similar in each case and that would be something like this
(example of call stack for System.Windows.Media.Animation.AnimationClock)
AnimationTimeline.AllocateClock()
Clock.AllocateClock(Timeline, bool)
ClockGroup.BuildClockSubTreeFromTimeline(Timeline, bool)
Clock.BuildClockTreeFromTimeline(Timeline, bool)
Timeline.CreateClock(bool)
Storyboard.BeginCommon(DependencyObject, INameScope, HandoffBehavior, bool, long)
Storyboard.Begin(FrameworkElement, HandoffBehavior, bool)
Storyboard.Begin(FrameworkElement, HandoffBehavior)
IndicatorBase.OnValueChanged(double, double)
IndicatorBase.ValuePropertyChangedHandler(DependencyObject, DependencyPropertyChangedEventArgs)
DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs)
FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs)
DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs)
DependencyObject.UpdateEffectiveValue(EntryIndex, DependencyProperty, PropertyMetadata, EffectiveValueEntry, EffectiveValueEntry&, bool, OperationType)
DependencyObject.InvalidateProperty(DependencyProperty)
BindingExpression.Invalidate(bool)
BindingExpression.TransferValue(object, bool)
BindingExpression.ScheduleTransfer(bool)
ClrBindingWorker.NewValueAvailable(bool, bool, bool)
PropertyPathWorker.UpdateSourceValueState(int, ICollectionView, object, bool)
PropertyPathWorker.UpdateSourceValueState(int, ICollectionView)
PropertyPathWorker.OnPropertyChangedAtLevel(int)
ClrBindingWorker.OnSourcePropertyChanged(object, string)
PropertyPathWorker.System.Windows.IWeakEventListener.ReceiveWeakEvent(Type, object, EventArgs)
WeakEventManager.DeliverEventToList(object, EventArgs, WeakEventManager.ListenerList)
PropertyChangedEventManager.OnPropertyChanged(object, PropertyChangedEventArgs)
MonitoringElement.NotifyPropertyChanged(string)
MonitoringPerformanceCounter.set_Value(float)
MonitoringPerformanceCounter.UpdateMonitoringElementIndicators()
MonitoringGroup.UpdateGroupElementsIndicators()
MonitoringGroupList.UpdateMonitoringElementsIndicatorsInAllGroups()
MonitoringServerInfoHolder.UpdateIndicators()
Dashboard.UpdaterTimer_Tick(object, EventArgs)
DispatcherTimer.FireTick(object)
So, as you can see those objects are created in response to update RadGauge's value and most probably they are created to perform smooth moving from previous value to new one.
Unfortunately, I can't attach the Profiler screen shots as I didn't found if this is possible in your forums.
So do you how can I release those unneeded resources?
Any help will be appreciated.
Thanks