N. Jalowski
N. Jalowski

Reputation: 41

Memory Leak using OxyPlot with Mono/C#

I’m using OxyPlot (v1.0.0) to draw a diagram with Mono/C#. It is running on embedded linux by the runtime environment of Mono.

Every time I update the plot or it updates itself more memory is claimed. This is done by my code (InvalidatePlot call) or by OxyPlot itself (for example when I swipe over the plot and the tracker is shown). Even by changing the window size this problem is triggered.
The programs memory shown by the task manager starts at 30 MB and climbs up to 400 within 20 minutes, where the application freezes and crashes later. Additionally, the following outputs are shown on the console:

(Testsoftware:673): Glib-Critical **: Source ID XXX was not found when attempting to remove it

I don’t know whether this is the real problem. I used the Mono profiler to get some information about the calls and heap composition. To my surprise at the time the program crashes the by the heapshot shown allocated memory is only around 9 MB, and no object provided by OxyPlot is part of the major ten. Where does this come from, when it does not affect the heap?
Even Valgrind did not help to find the problem. It was conspicuous that while the task manager recorded 60 MB of memory growth, Valgrind took just 4 MB in its statistics. The biggest part of the stacktraces could not be resolved because Valgrind did not take a look into Monos JIT.

For manually updating the plot its model needs to be updated explicitly. These are the things I tried in my code, but all of them cause the allocated memory to grow:

The method call summary shows also, that a massive amount of calls are GLib.Timeout/TimeoutProxy:Handler() calls. Maybe this could be an indication.

I think that it is a problem by OxyPlot. But I hope someone can help me – Thanks!

EDIT: Code snippet to reproduce. By swiping over the plot the tracker appears - and the memory goes up. This is just one way to get the plot updated, but all others also cause the problem.

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 as created by the designer tool:

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);
    }
}

Upvotes: 2

Views: 820

Answers (1)

N. Jalowski
N. Jalowski

Reputation: 41

After a lot of debugging I found out that I will not be able to solve the problem. The bug is located inside of OxyPlot.

Upvotes: 2

Related Questions