RadDocking closing panes does not reclaim memory in WPF

1 Answer 26 Views
Docking GridView
Patrick
Top achievements
Rank 1
Patrick asked on 27 Dec 2022, 07:45 PM

Hello,

I am working on a project based application, like visual studio, that requires the pane to be completely removed from working memory to avoid "Out of Memory" errors. 

The problem is that the PaneViewModel stores the content (in my case a UserControl), as intended, but when that PaneViewModel instance is removed from the MainWindowViewModel.Panes Collection, the memory (in diagnostic tools) shows it is not being reclaimed.

My assumption is that GC is not collecting the removed PaneViewModel because some how the UserControl or Pane is still referenced somewhere by the DocumentHost or RadDocking.

I've attached a modified version of the VisualStudioDocking example project that recreates/demonstrates the behavior I've described above. During runtime, please add new documents and close them at least 10 times to notice how big the difference is in memory over time. 

 

Regards,

Patrick

Patrick
Top achievements
Rank 1
commented on 27 Dec 2022, 09:14 PM

Update: I was able to reclaim a portion of the memory with this code by adding 
base.RemovePane(pane);
Does not reclaim all the memory, but some is better than none, hope this helps whoever can figure out the solution.
protected override void RemovePane(RadPane pane)
        {
            base.RemovePane(pane);

            pane.Header = null;
            pane.DataContext = null;
            pane.Content = null;
            pane.ClearValue(RadDocking.SerializationTagProperty);
            pane.RemoveFromParent();

            GC.Collect();
        }

1 Answer, 1 is accepted

Sort by
1
Accepted
Martin Ivanov
Telerik team
answered on 28 Dec 2022, 09:11 AM

Hello Patrick,

Your idea with setting the pane's content properties to null is a good one in order to avoid memory issues. However, there is a memory issue in the WPF framework, related to the automation peers that is inherited by the docking component and it can manifest sometimes. This said, can you try to disable the automation peers and see if the issue still persists on your side?

public MainWindow()
{
    AutomationManager.AutomationMode = AutomationMode.Disabled;
    InitializeComponent();
}

Regards,
Martin Ivanov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Patrick
Top achievements
Rank 1
commented on 04 Jan 2023, 05:27 PM

Hello Martin,

Thank you, I've actually added a few things including your code after posting the problem and it did help a little bit (around ~40% of the memory reclaimed. I added a few other things too below incase anyone needs it in the future.

public App()
        {
            TouchManager.IsTouchEnabled = false; 
            AutomationManager.AutomationMode = AutomationMode.Disabled;
        }

 

protected override void RemovePane(RadPane pane)
        {
            var group = pane.PaneGroup;
            if (group != null)
            {
                group.Items.Remove(pane);
            }

            pane.Header = null;
            pane.DataContext = null;
            pane.Content = null;
            pane.ClearValue(RadDocking.SerializationTagProperty);
            pane.RemoveFromParent();

            base.RemovePane(pane); //This line helps a good bit for some reason.

            pane = null;

            GC.Collect(); //May not be needed here. Placed this in OnClose in my application and still worked.
        }

 

With everything above, whether it helps or not, actually brought down memory consumption around (~90%) when I added it to this post's attached project. ~90% is currently enough for me to move forward but I will likely revisit this problem in the near future.

Hopefully this can uncover why this occurs or whoever needs help with a similar problem.

Thank you,

Patrick.

Patrick
Top achievements
Rank 1
commented on 04 Jan 2023, 05:29 PM

Also the order in which the code happens matters a good bit for 
protected override void RemovePane(RadPane pane)
Martin Ivanov
Telerik team
commented on 05 Jan 2023, 02:03 PM

Thank you for sharing your solution. I've memory profiled it in the original project posted here and I couldn't recreate any memory leaks related to this. Note that the GC.Collect() call doesn't promise that the memory will be collected immediately. If you still experience memory issues, the garbage collector may not released the memory yet. In case, you believe that there is still an issue, I would suggest you to memory profile the application and send over what exactly leaks based on the information from the profiling tool.
Tags
Docking GridView
Asked by
Patrick
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Share this question
or