Memory Issue: Screen.TryClose(), Deactivate not releasing memory.

Oct 6, 2012 at 9:03 PM
Edited Oct 6, 2012 at 9:07 PM

Hi, We are having hard time to understand this and identify memory issue. 

Our application is a Silverlight 4.0, with Caliburn Micro and using Autofac. Every screen is being opened is displayed in a TAB. 

Somehow screens are not releasing memory after closing/deactiving. We opened a ticket with Microsoft hoping that its a Silverlight issue, but the support guy after analyzing said that the Screen is not getting released and is a problem within CaliburnMicro. 

Created a sample project (SilverlightTabsApp) to reproduce our issue. (https://skydrive.live.com/redir?resid=F034D77F7A7A272B!279&authkey=!AKb61ewVnduKTvw)

Memory is not clearing and see screens being not released. We validated this using windbg and debugDiag tool (checking privates bytes that never coming down after closing all tabs).

Is the issue with our project setup or with caliburn micro? 

Oct 6, 2012 at 11:05 PM

Hi,

I cleaned up your sample (mostly remove styles and storyboards), removed all not used code.
Also OpenTab() and OnAllTabsClosed() was changed to prevent initialization of Tabs that are not shown (activated).

Caliburn.Micro is doing right: watch Activate/Deactivate messages in Visual Studio Ouput window

The modified source can be found here: https://skydrive.live.com/redir?resid=6F7C8BF0A544D7FA!254

May you reevaluate it. What objects are not released?

Oct 9, 2012 at 2:21 PM
Thank you tibel for a quick response.
I am trying to build the sample that is leaking the memory and per our understanding screen is the one.
The sample you have updated, I do see that memory is always stays same after initial tabs creation, may be screen is being reused but I never see the memory coming to same as what it was when app first started/loaded (45MB) even after closing all tabs.

We are trying to strip out our actual app to remove all db and services to make a sample that leaks the memory and go from there.


Thank you,
Rajesh C





On Oct 6, 2012, at 5:05 PM, "tibel" <notifications@codeplex.com> wrote:

From: tibel

Hi,

I cleaned up your sample (mostly remove styles and storyboards), removed all not used code.
Also OpenTab() and OnAllTabsClosed() was changed to prevent initialization of Tabs that are not shown (activated).

Caliburn.Micro is doing right: watch Activate/Deactivate messages in Visual Studio Ouput window

The modified source can be found here: https://skydrive.live.com/redir?resid=6F7C8BF0A544D7FA!254

May you reevaluate it. What objects are not released?

Oct 9, 2012 at 2:46 PM

To be sure that the screen is collected properly, implement the finalizer and put there a meaningful Debug.WriteLine or a breakpoint. If the finalizer is hit, memory is going to be freed correctly. 

Note that there is an high chance that the memory will never be back to the same amount as at startup. The .NET framework can create some objects as soon as a class is accessed for the first time, so checking just the amount of memory is meaningless. Moreover, a delayed garbage collection can cause false positives.

The simplest way to identify a memory leak is to test a routine, forcing a garbage collection (and waiting for pending finalizers) at each cycle. As an example, startup the application, open a screen, keep note of the memory once the screen is fully displayed, close it, start a garbage collection and wait for pending finalizers, open a new screen of the same type, wait until the screen is completely initialized and check if the amount of memory is (more or less) the same as when the first screen was completely initialized. Another way could be to open and close screens multiple times (from 10 to 100 or more times) and check if the memory allocation is steadly increasing.

Oct 12, 2012 at 11:29 PM
Edited Oct 12, 2012 at 11:36 PM

Thank you BladeWise, i tried all the options and it turned out ..... see below...

After doing some reverse engineering my code and stripping down one at a time, found the problem. 

We open screens in a new tab, and we have a custom tab, list box -> list items acts as a tabs and beneath there is a content control which displays currently selected screen. Per business requirement we created a copy/paste behavior and attached to listbox list item (textbloxk) using datatemplate.

It turned out that the behavior is the culprit, if i remove the behavior and i see screens being finalized properly. I googled and saw some posts suggesting that there is a leak with behaviors and suggested some solutions, but still no luck. Though it is calling detach/unload, i see the behavior being detached but the object is not getting finalized.

I am not sure if this is the issue because of using behavior on a control that is databound/message.attach using caliburn micro? (I don't think but..)

here is the code that has the issue: https://skydrive.live.com/redir?resid=F034D77F7A7A272B!285&authkey=!ANtMIlvZGbC5pYY

I added Destructor on viewmodel and added log to output window to see if it getting finalized, and in couple of passes (not immediately after closing the screen though), i see its getting called.