Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory leak in vector mode

Hi,

when I add plots in the "Vector" mode I see a leak in the VectorRenderTarget object.
When the app start, there are 4 instances of VectorRenderTarget. After adding plots, the number of this objects increases, and when clearing the data the number of objects is same and not decreases, and when I add plots again, the number of objects increases again.
When I switch to a "Raster" mode ,it has been resolved.

But I want to use Vector mode.

I check the memory with the VS analyze tool, attached my project.

Download All
0 Kudos
Message 1 of 9
(4,321 Views)

When the app start, there are 4 instances of VectorRenderTarget. After adding plots, the number of this objects increases . . . and when I add plots again, the number of objects increases again.

For Vector rendering, the graph uses a separate render target to host the WPF visuals for each plot (and child elements like grid lines and cursors are always rendered as vector objects). As more plots are added, the number of render targets should increase proportionately.

 


...when clearing the data the number of objects is same and not decreases,

Keep in mind that .NET is a garbage-collected runtime, which means that unused objects are not necessarily reclaimed immediately. Instead, when the application is idle or under memory pressure, .NET will automatically search for unused objects and reclaim them later on. To detect a managed memory leak, you would expect to see unused objects remaining in memory even after forcing a garbage collection (which I could not reproduce in your test application).

 


When I switch to a "Raster" mode ,it has been resolved.

For Hardware/Raster rendering, all plots are drawn to a single shared bitmap, so we do not need separate render targets to contain separate plot visuals.

~ Paul H
0 Kudos
Message 2 of 9
(4,299 Views)

Hi,
Even when I force the GC to collect after clear, the number of objects does not decrease.
I saw in Analyze that they have handlers to a size changed event (attached pic).

 

Capture.PNG

 

It seems that missing unregister from size changed event, so the GC can not collect them.

0 Kudos
Message 3 of 9
(4,289 Views)

Thank you for following up with more detail: it does appear that we leak empty render target objects in vector when plot data is removed from the graph. I have created a task to address this issue.

 

In general, I would not expect this leak to cause a performance problem in most cases (the size of the render target itself is small, and all of the associated WPF visuals are cleared before the target is leaked). As a workaround, if you temporarily change the RenderMode of the graph and then set it back to Vector, that will clear out all of the old render targets in the graph.

~ Paul H
0 Kudos
Message 4 of 9
(4,271 Views)

Even when I change the render in the "clear" function, the objects are still leaks because they are still registered to the SizeChanged event.

In the above example project, it is a small leak. But in our original project there are many changes of plots in large quantities and a many use of graphs, so it causes serious memory problems.

A much larger leakage can occur when the MajorGridLines of axis changed (for example, when it depend on the property through binding).

I added to the attached project a button that changes the MajorGridLines 100 times just for proof and you can see that this leak gradually increases each time the button is pressed, and if you change to 1M the loop count you can reach to OutOfMemory.

[This can happen in the use of our project over a long period of time, when we exchanged lots of data and lots of graphs in many tools.]

0 Kudos
Message 5 of 9
(4,252 Views)

Sorry for the incorrect workaround: I had been testing on a pre-release version that already included a fix for the leaked SizeChanged event registration. In that case, I believe it is still possible to avoid leaking the empty render targets by maintaining (empty) data collections for those plots (instead of clearing them/setting them to null).

 

I was also able to reproduce the grid line object memory leak, and have started investigating. Note that this does not match the typical use case, where you would set the MajorGridLines once, and then just change properties on the grid lines object to change the visuals (even without the leak, creating a new grid lines object will always be more expensive than changing a property on an existing object).

~ Paul H
0 Kudos
Message 6 of 9
(4,244 Views)

Thank you, but setting the data source to null did not solve the plot leakage .

do you have other workaround?

 

Changing the property StrokeDashArray instead of creating a new grid line object ,also cause to a leak.

0 Kudos
Message 7 of 9
(4,222 Views)

Apologies again (that’s what I get for trying to rush out an answer before the end of the year!). Looking at the logic for displaying grid lines, I see that we go through the same code path whether you are assigning a completely new grid lines object or just changing a property on an existing one. It is possible to work around this by disabling grid lines on the axis and manually including a grid lines renderer in the Children collection, but the setup is a little difficult — are you making frequent changes to grid lines, or was this just something else you noticed in your testing?

 

Regarding data, the example application used this code to demonstrate the plot leak:

public void ClearData()
{
    for (int i = 0; i < Data.Count; i++)
    {
        Data[i].Capacity = 1;
        Data[i].Clear();
        Data[i] = null;
    }
    Data.Clear();
}

My suggestion was to "maintain empty data collections for those plots", and avoid assigning null:

public void ClearData()
{
    for (int i = 0; i < Data.Count; i++)
    {
        Data[i].Clear(); // (leave the chart in the Data collection; just clear it of accumulated samples)
    }
}

After updating the code to re-using the cleared chart collections, this does improve the memory performance on my machine (but does not appear to completely eliminate the leak, so we are still investigating).

~ Paul H
0 Kudos
Message 8 of 9
(4,205 Views)

Just wanted to let you know this issue was fixed in the Measurement Studio 2019 release.

~ Paul H
0 Kudos
Message 9 of 9
(3,320 Views)