Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does continual removing and re-adding of a DrawingVisual cause a constant increase in memory usage?
    primarykey
    data
    text
    <p>I've got a WPF program that uses a <code>Canvas</code> within a <code>Window</code>, over-ridden to become a <code>Graphics_Canvas</code>, which looks like this:</p> <pre><code>class Graphics_Canvas : Canvas { private List&lt;DrawingVisual&gt; visuals = new List&lt;DrawingVisual&gt;(); protected override int VisualChildrenCount { get { return visuals.Count; } } protected override Visual GetVisualChild(int index) { return visuals[index]; } public void AddVisual(DrawingVisual visual) { visuals.Add(visual); base.AddVisualChild(visual); base.AddLogicalChild(visual); } public bool ContainsVisual(DrawingVisual visual) { return visuals.Contains(visual); } public bool HasVisuals { get { return visuals.Count &gt; 0; } } public void RemoveAllVisuals() { for (int i = 0; i &lt; visuals.Count; i++) { base.RemoveVisualChild(visuals[i]); base.RemoveLogicalChild(visuals[i]); } visuals.Clear(); } public void RemoveLastVisual() { if (visuals.Count &gt; 0) { int index = visuals.Count - 1; base.RemoveVisualChild(visuals[index]); base.RemoveLogicalChild(visuals[index]); visuals.Remove(visuals[index]); } } public void RemoveVisual(DrawingVisual visual) { base.RemoveVisualChild(visual); base.RemoveLogicalChild(visual); visuals.Remove(visual); } } </code></pre> <p>(I did get that from somewhere online but I cannot remember where as it was a while ago.)</p> <p>Anyway, the program allows the user to pan the graphics displayed on the <code>Graphics_Canvas</code> by dragging with the middle mouse, and this will continually (as long as they keep panning) trigger something like this:</p> <pre><code> //get the data visual: DrawingVisual tempVisual = GetDataDrawingVisual(); //first clear the current display data: myCanvas.RemoveVisual(dataVisual); //get the data visual: dataVisual = tempVisual; myCanvas.AddVisual(dataVisual); </code></pre> <p>So I continually remove and then re-add the <code>dataVisual</code>.</p> <p>What I notice when I look at memory use is that panning around causes memory use to increase, and while it does drop down again, it doesn't go all the way to what it was before. This is even more pronounced when nothing is on the display at all, and the memory use of continually re-adding effectively nothing can rise to hundreds of MB, again dropping mostly when panning stops.</p> <p>For information, I should add that <code>GetDataDrawingVisual()</code> returns a <code>Visual</code> onto which is drawn a <code>RenderTargetBitmap</code>, which itself is not retained outside of that method.</p> <p>My question is why does this cause memory usage to vary so much?</p> <p>Currently this is more of a curious nuisance, but I can foresee that it could be a problem if the available memory was more limited to begin with.</p> <p>Any insights would be greatly appreciated.</p> <p><strong>* UPDATE (21/03/2013) *</strong></p> <p>From experimenting with the <code>Graphics_Canvas</code>, it appears that the following method makes a fair impact on how much memory is not released:</p> <pre><code>protected override Visual GetVisualChild(int index) { return visuals[index]; } </code></pre> <p>If I just return a <code>new DrawingVisual()</code> instead as a test, memory goes back to pretty much where it was after re-drawing ends.</p> <p>However, removing this method just means that the <code>Canvas</code> won't run, and I'll get an error. Could it be that somewhere behind the scenes .NET is making a reference to the <code>Visual</code> returned from this method and then not de-referencing it later? How could I sort this? (Note: I never explicitly call this method in my code, it is called from somewhere else).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload