-
kereszte said 1 year, 12 months ago:
Hi,
I am working on a project that requires real-time plotting and I must display a number of limits in the plots (horizontal lines) and I’m using YFunctionSeries to display them. It appears that everytime I change the Min and Max values in the series, I create a memory leak.
I have C1WPFChartSamples2010 installed on my system and I modified the Dynamic example to prove the issue (couldn’t upload the xaml files as one of the extensions are not allowed…) :
In XAML, replace the C1Chart with this and add the XML namespace(only added the YFunctionSeries):
<c1chart:C1Chart x:Name="chart" Style="{StaticResource CE_SampleChart}" > <c1chart:C1Chart.Data> <c1chart:ChartData> <Extended:YFunctionSeries x:Name="sampleSeries" Label="USL" ChartType="Line" SampleCount="2" Min="0" ConnectionFill="Red"/> </c1chart:ChartData> </c1chart:C1Chart.Data> <c1chart:C1ChartLegend Foreground="#FFF0F8FE"/> </c1chart:C1Chart>in the Dynamic.xaml.cs file, replace the update function with this:
private const string DoubleFormat = "0.00″; private int _currentPoint = 0; void Update() { chart.BeginUpdate(); int cnt = nAddPoints; for (int i = 0; i < cnt; i++) { _currentPoint++; double r = rnd.NextDouble(); double y = (10 * r * Math.Sin(0.1 * counter) * Math.Sin(0.6 * rnd.NextDouble() * counter)); _pts.Add(new Point(counter++, y*100)); } int ndel = _pts.Count - nMaxPoints; if (ndel > 0) for (int i = 0; i < ndel; i++) _pts.RemoveAt(0); double r2 = rnd.NextDouble(); double y2 = (10 * r2 * Math.Sin(0.1 * counter) * Math.Sin(0.6 * rnd.NextDouble() * counter)); sampleSeries.FunctionCode = (y2*100).ToString(DoubleFormat); sampleSeries.Min = _currentPoint; sampleSeries.Max = _currentPoint – nMaxPoints; chart.EndUpdate(); }Simply let the dynamic example run for a few minutes and you’ll notice that every-update causes the program to increase in size a few hundred kb, and this continues indefinitely.
Due to the rate at which memory increases, this is quite a problem for my project. Is this a known issue?
Thanks
AJBTW- attaching files on this editor is terrible in Firefox. It won’t let me upload the xaml file (extension not allowed) and I couldn’t remove the attachments from the list so I had to start a new message…
| # -
Hi,
It looks like the problem is related with Microsoft.JScript.Eval.JScriptEvaluate() method which is used for evaluating expression in function series. Do you need to calculate an arbitrary formula at runtime?
–
Best regards,
Alex| # -
kereszte said 1 year, 12 months ago:
Hi Alex,
If you change my example to set the FunctionCode only once but change the Min/Max range in every update, the system still leaks memory.
Does the chart re-evaluate the formula when the Min/Max ranges are changed? The issue is that even if I set the FunctionCode once, memory still leaks.
Example update code that only sets FunctionCode the first time through:
private const string DoubleFormat = "0.00″; private int _currentPoint = 0; void Update() { chart.BeginUpdate(); if (_currentPoint == 0) { double r2 = rnd.NextDouble(); double y2 = (10 * r2 * Math.Sin(0.1 * counter) * Math.Sin(0.6 * rnd.NextDouble() * counter)); sampleSeries.FunctionCode = (y2 * 100).ToString(DoubleFormat); } int cnt = nAddPoints; for (int i = 0; i < cnt; i++) { _currentPoint++; double r = rnd.NextDouble(); double y = (10 * r * Math.Sin(0.1 * counter) * Math.Sin(0.6 * rnd.NextDouble() * counter)); _pts.Add(new Point(counter++, y*100)); } int ndel = _pts.Count - nMaxPoints; if (ndel > 0) for (int i = 0; i < ndel; i++) _pts.RemoveAt(0); sampleSeries.Min = _currentPoint; sampleSeries.Max = _currentPoint – nMaxPoints; chart.EndUpdate(); }| # -
It does not matter how many times you set the FunctionCode. When you set it once all function calculations are performed using Microsoft.JScript.Eval.JScriptEvaluate() which is the main source of leaks(according to my research). Of course, the values of function are re-calculated when you change the range.
I repeat my question: do you need to change the formula at runtime?
There are other methods to calculate expression, perhaps I can advise something.–
Best regards,
Alex| # -
kereszte said 1 year, 11 months ago:
Yes I do.
Currently, this is a gaping memory hole in which nothing returns. If I let our real-time report run for an hour, our program will use over a gig of ram.
The real-time report sets the expression once, but changes the range as it runs. It seems that the YFunctionSeries will not automatically set its range to the underlying chart range. (or can it?) Changing the range is what causes the leak.
Our other reports set the expression at run-time as well, but it’s not performed at the rate of the real-time report.
Any fix would be helpful.
AJ| # -
As I said before I think the leak is related with MS JScript engine and not related with the range.
Could you please try to use another expression engine that is more appropriate for realtime calculation. It can be easy added to the existing function class. E.g. below I’ve created the function series that uses Fleehttp://flee.codeplex.com
public class MyYFunction : YFunctionSeries { Ciloci.Flee.ExpressionContext context; Ciloci.Flee.IDynamicExpression expr; string code; public MyYFunction() { context = new Ciloci.Flee.ExpressionContext(); context.Variables["val"] = 0.0; Function = Calculate; } double Calculate(double val) { if( expr!=null) { context.Variables["val"] = val; return (double)expr.Evaluate(); } return 0.0; } public new string FunctionCode { get { return code;} set { if( code!=value) { code = value; expr = context.CompileDynamic(code); base.UpdateData(); } } } }–
Best regards,
Alex| #
You must be logged in to reply to this topic.

