Memory Leaks in UIElement.Arrange()

I'm using Microsoft Prerelease Software WinFX Runtime Components (February CTP Build).

I have memory leaks in with UIElement.Arrange(). If you run the following code:

class WPFMemoryLeak
{
public static void Main(String[] args)
{
long initialMem = GC.GetTotalMemory(false);

int counter = 0;
while (true)
{
Rect rect = new Rect(0, 0, 300, 300);
UIElement ui = new UIElement();
ui.Arrange(rect);

if (++counter > 100)
{
long memoryBeforeGC = GC.GetTotalMemory(false);

GC.Collect(3);
GC.WaitForPendingFinalizers();
GC.Collect(3);

long memoryAfterGC = GC.GetTotalMemory(false);

Console.WriteLine(
"Initial: " + initialMem.ToString() +
" before GC: " + memoryBeforeGC.ToString() +
" after GC: " + memoryAfterGC.ToString()
);

counter = 0;
}
}
}
}

You will see that memory is allocated all the time:

Initial: 298492 before GC: 965548 after GC: 957424
Initial: 298492 before GC: 989176 after GC: 982068
Initial: 298492 before GC: 1010516 after GC: 1006712
Initial: 298492 before GC: 1039480 after GC: 1031356
Initial: 298492 before GC: 1061380 after GC: 1056000
Initial: 298492 before GC: 1088768 after GC: 1080644
Initial: 298492 before GC: 1112236 after GC: 1105288

After I commented ui.Arrange(rect) line and run the application again I didn't see any memory leaks:

Initial: 298492 before GC: 357632 after GC: 333056
Initial: 298492 before GC: 357632 after GC: 333056
Initial: 298492 before GC: 357632 after GC: 333056
Initial: 298492 before GC: 357632 after GC: 333068
Initial: 298492 before GC: 357644 after GC: 333056

What could be a reason Is it a known bug

My goal is to render XAML into image on server side. I'm using RenderTargetBitmap class. In order to see XAML shapes on image I need to call Arrange() on XAML root element (after loading it to objects tree) before rendering.

Are there any other ways to render XAML into image which will not result in memory leaks

Regards, Andrey





Answer this question

Memory Leaks in UIElement.Arrange()

  • Eagle 101

    Solved the issue.

    The solution is to add ui.UpdateLayout() after ui.Arrange(rect).

    The problem was - UIElement.Arrange - creates SizeChangedInfo that has a reference to UIElement. SizeChangedInfo object is registered to ContextLayoutManager that puts it into _sizeChangedChain.

    This chain is cleared by ContextLayoutManager.fireSizeChangedEvents() that is (eventually) called by UIElement.UpdateLayout().

    Regards,

    Andrey



  • Memory Leaks in UIElement.Arrange()