1

I'm using WPF to develop a simulator of Conway's Game of Life.

From some reason, sometimes the program takes up to 400,000K memory (When I draw a lot of cells really fast).

How can I reduce the memory usage and/or reduce the lags caused by it.

Edit 1: Main Window Code: http://pastebin.com/mz0z7tBu

Grid class: http://pastebin.com/ZHX1WBuK

cell struct:

struct Cell
{
    public int Neighbors {get; set;}
    public bool Alive { get; set; }
}

Edit 2: I'll try to explain Program Structure: Cell is a structure that contains AutoProperty neighbors ofType int, and AutoProperty IsAlive ofType bool.

CellGrid is a Class that wraps a 2D array of Cells. Every iteration, each Cell's Neighbors property is updated to contain the number of Neighbors alive, and then each Cell's IsALive is set to true or false, depends on number of neighbors and previous IsAlive state.

The MainWindow class has an object of type CellGrid. It renders the grid to the screen.

Edit 3:

XAML: http://pastebin.com/Zp3dr8zc

resources.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="MaxHeight" Value="32" />
    </Style>
    <Style TargetType="{x:Type MenuItem}" x:Key="ParentMenuItem">
        <Setter Property="Width" Value="46" />
    </Style>
</ResourceDictionary>
H.B.
  • 166,899
  • 29
  • 327
  • 400
Gilad Naaman
  • 6,390
  • 15
  • 52
  • 82
  • 4
    It will be difficult for anyone to offer guidance without seeing the code. – bronsoja Jun 23 '11 at 04:22
  • how do you control the timing between generations? – DXM Jun 23 '11 at 04:23
  • Drawing code or cell code? @DMX There is no timing. Generations are passed in a click of a button. – Gilad Naaman Jun 23 '11 at 04:23
  • @Gilad Naaman: rather than / before sharing the code, try a high level _presentation_ of the program structure: eg. the Cell: what are they, how big, when/how are they created, which modules use them. eg. the the "Generation manager", etc. etc. You may find that in explaining the problem at the right amount of precision you may give yourself ideas as the possible sources of excessive memory use. – mjv Jun 23 '11 at 04:28
  • Added Program structure + Code – Gilad Naaman Jun 23 '11 at 04:36
  • You've gone so far with providing code, so why not post the XAML as well to eliminate some guesswork for us? :) – Dave Jun 23 '11 at 04:52
  • @Gilad: I was able to get some XAML together to make the program run. Can you be a little clearer about how the memory usage increases? Is it from continuous clicking of the buttons? Clicking and dragging the mouse around in `display`? – Dave Jun 23 '11 at 05:00
  • Clicking and dragging the mouse around display in an average speed increases the memory usage dramatically. – Gilad Naaman Jun 23 '11 at 05:02
  • @Gilad yes, I have confirmed that. Like **gigabytes** of memory used by drawing a few circles. – Dave Jun 23 '11 at 05:17

1 Answers1

4

This is the result of using a DrawingContext/DrawingVisual. It's actually benign and should all be garbage collected as the system needs it, but the memory usage can be alarming. If you were to, instead, draw shapes on a canvas then you would probably not see this problem. I've run into this same issue with custom drawn controls in the past. Switching to more vector-based drawing techniques (i.e., shapes on a canvas) fixed the memory consumption problem.

JacobJ
  • 3,677
  • 3
  • 28
  • 32
  • Thank you :). Do you have a learning source for canvas usage? – Gilad Naaman Jun 23 '11 at 05:06
  • 1
    They may be kind of complex to learn from, but my project, WPFSVL, has an example of this (http://wpfsvl.codeplex.com). The spectrum analyzer control used to do fast rendering with a DrawingContext and DrawinVisual, but I changed it to use shapes instead. When I did, I saw a situation similar to yours. It used to "take up" hundres of MB of memory, but now an entire app takes up like 30 MB. – JacobJ Jun 23 '11 at 05:19
  • For comparison, you can find some of the old source code that still used the DrawingVisuals here: http://inchoatethoughts.com/a-wpf-spectrum-analyzer-for-audio-visualization – JacobJ Jun 23 '11 at 05:20
  • So, how should I write it? Adding rectangles and change their Background property each Generation? – Gilad Naaman Jun 23 '11 at 05:23
  • 1
    Yep, exactly. Add Rectangles where you need them on the canvas and change their Fill property to change the color. My intuition used to be that this would be very slow compared to DrawingContext methods, but it really is surprisingly performant. – JacobJ Jun 23 '11 at 05:34
  • Working on that :). My problem is that Canvas's children property is a single dimensional array (list, actually), so I need to somehow transform the x/y position of a cell in the grid to a single i representing the rectangle on the canvas – Gilad Naaman Jun 23 '11 at 05:43