12-21-2017 04:24 AM
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.
12-21-2017 11:02 AM
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.
12-24-2017 02:56 AM - edited 12-24-2017 02:57 AM
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).
It seems that missing unregister from size changed event, so the GC can not collect them.
12-27-2017
02:04 PM
- last edited on
11-20-2024
09:08 AM
by
Content Cleaner
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.
12-28-2017 05:37 AM
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.]
12-28-2017
10:41 AM
- last edited on
11-20-2024
09:08 AM
by
Content Cleaner
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).
12-31-2017 05:19 AM
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.
01-02-2018
10:50 AM
- last edited on
11-20-2024
09:09 AM
by
Content Cleaner
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).
07-08-2019
02:11 PM
- last edited on
11-20-2024
09:09 AM
by
Content Cleaner
Just wanted to let you know this issue was fixed in the Measurement Studio 2019 release.