我已經創建了一個使用AvalonDock框架的應用程序。關鍵部分是使用派生編輯器編輯域模型實體的能力。我遇到了一個問題,並發現我的編輯在關閉並從DockingManager.Documents
集合中刪除後沒有進行垃圾回收。AvalonDock DocumentContent未垃圾回收
後,我創建了一個可以通過以下方式來重新創建一個小的測試應用程序的一些無覓處:
- 在Visual Studio(我使用的是2008年),創建一個名爲
AvalonDockLeak
一個新的WPF應用程序; - 添加對AvalonDock庫的引用(我的版本是1.3.3571.0);
- 添加一個名爲
Document
的新UserControl; 更改Document.xmal到:
<ad:DocumentContent x:Class="AvalonDockLeak.Document" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"> <Grid> <TextBox /> </Grid> </ad:DocumentContent>
更改Document.xmal.cs到:
namespace AvalonDockLeak { using AvalonDock; public partial class Document : DocumentContent { public Document() { InitializeComponent(); } ~Document() { } } }
析構函數我已經加入到能夠診斷添加的斷點問題方法打開{,看看它是否受到打擊。它總是關閉測試應用程序,但不會更早。
現在Window1.xaml更改爲:
<Window x:Class="AvalonDockLeak.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock" Title="Memory Leak Test" Height="300" Width="300"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <Button Name="NewButton" Click="NewButton_Click" Content="New" Height="26" Width="72" /> <ad:DockingManager x:Name="DockManager" Grid.Row="1"> <ad:DocumentPane /> </ad:DockingManager> </Grid> </Window>
更改Window1.xaml.cs到:
namespace AvalonDockLeak { using System.Windows; public partial class Window1 : Window { private int counter = 0; public Window1() { InitializeComponent(); } private void NewButton_Click(object sender, RoutedEventArgs e) { string name = "Document" + (++this.counter).ToString(); var document = new Document() { Name = name, Title = name, IsFloatingAllowed = false }; document.Show(this.DockManager); document.Activate(); } } }
這個簡單的應用程序還包含了泄漏。可以通過~Document()
開頭處的斷點(在關閉DocumentContent
後未被擊中)觀察到。
現在我想要的是,這是一個已知的問題,有沒有辦法來防止它?如果物體在很長一段時間後才被垃圾收集,那麼我能做些什麼來加速這個過程?調用GC.Collect()沒有幫助的方式。
檢查Avalon的源代碼,看看有什麼'document.Show(this.DockManager);'一樣。我猜文檔會以某種方式向管理員註冊,而且它沒有正確註銷。 DockManager上是否有方法去除文檔? – ChrisWue
它只是'manager.Documents.Add(this);'。文檔關閉後,它也不再存在於'manager.Documents'集合中。 – Wietze
那麼,找出的一種方法是附加一個內存分析器或進行內存轉儲,並使用windows的調試工具來找出引用的內容。 – ChrisWue