I have the following code that will throw an OutOfMemoryException on startup:
public partial class MainWindow : Window { private DrawingVisual myVisual = new DrawingVisual(); public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { myVisual = GetVisual(); graphicsCanvas.AddVisual(myVisual); } private void Graphics_Canvas_MouseMove(object sender, MouseEventArgs e) {
Where a Graphics_Canvas is defined as follows:
class Graphics_Canvas : Canvas { private List<DrawingVisual> visuals = new List<DrawingVisual>(); 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 > 0; } } public void RemoveAllVisuals() { for (int i = 0; i < visuals.Count; i++) { RemoveFromLogicalTree(visuals[i]); } visuals.Clear(); } private void RemoveFromLogicalTree(Visual visual) { RemoveLogicalChild(visual); RemoveVisualChild(visual); } public void RemoveLastVisual() { if (visuals.Count > 0) { int index = visuals.Count - 1; RemoveFromLogicalTree(visuals[index]); visuals.Remove(visuals[index]); } } public void RemoveVisual(DrawingVisual visual) { RemoveFromLogicalTree(visual); visuals.Remove(visual); } }
And the XAML for creating the Window looks like this:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:csMemoryLeakTestProject" x:Class="csMemoryLeakTestProject.MainWindow" Title="MainWindow" Background="Gray" Height="600" Width="800" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded"> <Grid> <local:Graphics_Canvas Margin="12" Background="White" x:Name="graphicsCanvas" MouseMove="Graphics_Canvas_MouseMove"/> </Grid> </Window>
Now, this is just an example to illustrate my point, namely that I donβt understand that the alternative here is to use the Garbage Collector ...
If you run the program and continue to move the mouse over Graphics_Canvas , using memory builds, builds and builds until you get an OutOfMemoryException . If you add to GC.Collect() , where I commented on this, this will not happen (although the memory increases by a small amount, for reasons beyond me, and, I hope, is related to my problem), and the program continues to function.
So why doesn't the GC hit and clear this memory and stop the exception from occurring? If I make a very fundamental mistake, I would be very happy if someone pointed me to this so that I could move on.
I have met many times on this website and other programmer tips saying, "Never use a garbage collector." I want to comply with best practice, but I do not see in such situations what else I could do.