Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 66147
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 10, 20262026-05-10T19:03:28+00:00 2026-05-10T19:03:28+00:00

I have boiled down an issue I’m seeing in one of my applications to

  • 0

I have boiled down an issue I’m seeing in one of my applications to an incredibly simple reproduction sample. I need to know if there’s something amiss or something I’m missing.

Anyway, below is the code. The behavior is that the code runs and steadily grows in memory until it crashes with an OutOfMemoryException. That takes a while, but the behavior is that objects are being allocated and are not being garbage collected.

I’ve taken memory dumps and ran !gcroot on some things as well as used ANTS to figure out what the problem is, but I’ve been at it for a while and need some new eyes.

This reproduction sample is a simple console application that creates a Canvas and adds a Line to it. It does this continually. This is all the code does. It sleeps every now and again to ensure that the CPU is not so taxed that your system is unresponsive (and to ensure there’s no weirdness with the GC not being able to run).

Anyone have any thoughts? I’ve tried this with .NET 3.0 only, .NET 3.5 and also .NET 3.5 SP1 and the same behavior occurred in all three environments.

Also note that I’ve put this code in a WPF application project as well and triggered the code in a button click and it occurs there too.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows.Shapes; using System.Windows;  namespace SimplestReproSample {     class Program     {         [STAThread]         static void Main(string[] args)         {             long count = 0;             while (true)             {                 if (count++ % 100 == 0)                 {                     // sleep for a while to ensure we aren't using up the whole CPU                     System.Threading.Thread.Sleep(50);                 }                 BuildCanvas();             }         }          [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]         private static void BuildCanvas()         {             Canvas c = new Canvas();              Line line = new Line();             line.X1 = 1;             line.Y1 = 1;             line.X2 = 100;             line.Y2 = 100;             line.Width = 100;             c.Children.Add(line);              c.Measure(new Size(300, 300));             c.Arrange(new Rect(0, 0, 300, 300));         }     } } 

NOTE: the first answer below is a bit off-base since I explicitly stated already that this same behavior occurs during a WPF application’s button click event. I did not explicitly state, however, that in that app I only do a limited number of iterations (say 1000). Doing it that way would allow the GC to run as you click around the application. Also note that I explicitly said I’ve taken a memory dump and found my objects were rooted via !gcroot. I also disagree that the GC would not be able to run. The GC does not run on my console application’s main thread, especially since I’m on a dual core machine which means the Concurrent Workstation GC is active. Message pump, however, yes.

To prove the point, here’s a WPF application version that runs the test on a DispatcherTimer. It performs 1000 iterations during a 100ms timer interval. More than enough time to process any messages out of the pump and keep the CPU usage low.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Shapes;  namespace SimpleReproSampleWpfApp {     public partial class Window1 : Window     {         private System.Windows.Threading.DispatcherTimer _timer;          public Window1()         {             InitializeComponent();              _timer = new System.Windows.Threading.DispatcherTimer();             _timer.Interval = TimeSpan.FromMilliseconds(100);             _timer.Tick += new EventHandler(_timer_Tick);             _timer.Start();         }          [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]         void RunTest()         {             for (int i = 0; i < 1000; i++)             {                 BuildCanvas();             }         }          [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]         private static void BuildCanvas()         {             Canvas c = new Canvas();              Line line = new Line();             line.X1 = 1;             line.Y1 = 1;             line.X2 = 100;             line.Y2 = 100;             line.Width = 100;             c.Children.Add(line);              c.Measure(new Size(300, 300));             c.Arrange(new Rect(0, 0, 300, 300));         }          void _timer_Tick(object sender, EventArgs e)         {             _timer.Stop();              RunTest();              _timer.Start();         }     } }  

NOTE2: I used the code from the first answer and my memory grew very slowly. Note that 1ms is much slower and less iterations than my example. You have to let it run for a couple minutes before you start to notice growth. After 5 minutes it’s at 46MB from a starting point of 30MB.

NOTE3: Removing the call to .Arrange completely eliminates the growth. Unfortunately, that call is pretty vital to my use since in many cases I’m creating PNG files from the Canvas (via the RenderTargetBitmap class). Without the call to .Arrange it doesn’t layout the canvas at all.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-10T19:03:28+00:00Added an answer on May 10, 2026 at 7:03 pm

    I was able to reproduce your problem using the code you provided. Memory keeps growing because the Canvas objects are never released; a memory profiler indicates that the Dispatcher’s ContextLayoutManager is holding on to them all (so that it can invoke OnRenderSizeChanged when necessary).

    It seems that a simple workaround is to add

    c.UpdateLayout() 

    to the end of BuildCanvas.

    That said, note that Canvas is a UIElement; it’s supposed to be used in UI. It’s not designed to be used as an arbitrary drawing surface. As other commenters have already noted, the creation of thousands of Canvas objects may indicate a design flaw. I realise that your production code may be more complicated, but if it’s just drawing simple shapes on a canvas, GDI+-based code (i.e., the System.Drawing classes) may be more appropriate.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 59k
  • Answers 59k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • added an answer The samples here http://msdn.microsoft.com/en-us/library/aa967565.aspx show how to use extensibility to… May 11, 2026 at 9:03 am
  • added an answer It can be done, but it's quite painful: You can't… May 11, 2026 at 9:03 am
  • added an answer Assign is renamed to Assign_ because of a mapping in… May 11, 2026 at 9:03 am

Related Questions

I have boiled down an issue I'm seeing in one of my applications to
I have a 'generic' boiler plate static method for checking for InvokeRequired and invoking
I have a web-service that I will be deploying to dev, staging and production.
I have the following tables in my database that have a many-to-many relationship, which
I have a .Net desktop application with a TreeView as one of the UI
I have a Queue<T> object that I have initialised to a capacity of 2,
I have an absolutely positioned div containing several children, one of which is a
I have heard umpteen times that we 'should not mix business logic with other
I have 2 hosts and I would like to point a subdomain on host
I have a complete XML document in a string and would like a Document

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.