【发布时间】:2018-11-28 21:26:24
【问题描述】:
我正在使用 OxyPlot (v1.0.0) 用 Mono/C# 绘制图表。它通过 Mono 的运行时环境在嵌入式 linux 上运行。
每次我更新情节或更新自己时,都会占用更多内存。这是由我的代码(InvalidatePlot 调用)或 OxyPlot 本身完成的(例如,当我在绘图上滑动并显示跟踪器时)。即使通过更改窗口大小也会触发此问题。
任务管理器显示的程序内存从 30 MB 开始,并在 20 分钟内攀升至 400,然后应用程序冻结并崩溃。此外,控制台上还会显示以下输出:
(Testsoftware:673): Glib-Critical **: Source ID XXX was not found when attempting to remove it
我不知道这是否是真正的问题。我使用 Mono 分析器来获取有关调用和堆组合的一些信息。令我惊讶的是,当程序崩溃时,堆显示分配的内存只有大约 9 MB,并且 OxyPlot 提供的任何对象都不是主要十个的一部分。当它不影响堆时,这是从哪里来的?
甚至 Valgrind 也没有帮助找到问题所在。值得注意的是,虽然任务管理器记录了 60 MB 的内存增长,但 Valgrind 在其统计数据中仅占用了 4 MB。堆栈跟踪的最大部分无法解析,因为 Valgrind 没有查看 Monos JIT。
要手动更新绘图,需要明确更新其模型。这些是我在代码中尝试过的事情,但所有这些都会导致分配的内存增长:
- Diagram.InvalidatePlot (true); (官方方法)
- Diagram.Model = myModel;
- 将 Diagram.Model 设置为 NULL 并新建
方法调用摘要还显示,大量调用是 GLib.Timeout/TimeoutProxy:Handler() 调用。也许这可能是一个迹象。
我认为这是 OxyPlot 的问题。但我希望有人能帮助我——谢谢!
编辑:代码 sn-p 重现。通过在绘图上滑动,跟踪器就会出现 - 并且内存会增加。这只是更新情节的一种方法,但所有其他方法也会导致问题。
using System;
using OxyPlot.GtkSharp;
using OxyPlot.Series;
using OxyPlot.Axes;
using OxyPlot;
using Gtk;
public partial class MainWindow: Gtk.Window
{
public MainWindow () : base (Gtk.WindowType.Toplevel)
{
Build ();
var model = new PlotModel ();
var plot = new LineSeries () { Title = "Plot", Color = OxyColors.Red, TrackerFormatString="Tracker" };
plot.Points.Add (new DataPoint (10, 5)); //Add two points to get a graph
plot.Points.Add (new DataPoint (5, 10));
model.Series.Add (plot); //Add plot to the model
model.Axes.Add (new LinearAxis { Title = "Bottom", Position = AxisPosition.Bottom}); //Add axes to the model
model.Axes.Add (new LinearAxis { Title = "Left", Position = AxisPosition.Left});
var diagramm = new PlotView();
diagramm.Model = model; //Add model to the view
diagramm.Visible = true;
alignment1.Add (diagramm); //Alignment1 lies in MainWindow
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}
}
由设计器工具创建的 MainWindow GUI:
public partial class MainWindow
{
private global::Gtk.Alignment alignment1;
protected virtual void Build ()
{
global::Stetic.Gui.Initialize (this);
// Widget MainWindow
this.Name = "MainWindow";
this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");
this.WindowPosition = ((global::Gtk.WindowPosition)(4));
// Container child MainWindow.Gtk.Container+ContainerChild
this.alignment1 = new global::Gtk.Alignment (0.5F, 0.5F, 1F, 1F);
this.alignment1.Name = "alignment1";
this.Add (this.alignment1);
if ((this.Child != null)) {
this.Child.ShowAll ();
}
this.DefaultWidth = 400;
this.DefaultHeight = 300;
this.Show ();
this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
}
}
【问题讨论】:
-
如果您能提供minimal reproducible example,那就太好了。
-
@mjwills 我上传了一个 sn-p 和其他一些新发现
标签: c# memory-leaks embedded-linux oxyplot