Dot-Net

我的 WPF 導航中是否存在記憶體洩漏?

  • April 2, 2021

我正在查看一個 WPF 應用程序以查找記憶體洩漏(使用 ANTS Memory Profiler 5.1),並且我一直看到一些頁面和控制項在不應該佔用記憶體時佔用了記憶體。

所以我去對象保留圖,看看是什麼讓它們保持不變,我在每一頁都看到這個:

對象保留圖 http://img683.imageshack.us/img683/3013/ants.jpg

問題是,我在每個頁面上都將 KeepAlive 設置為 false,而且我認為使用者控制項上不存在這樣的屬性。

誰能告訴我我應該尋找什麼?這甚至是記憶體洩漏還是 WPF 應用程序的正常行為?

是的,根據您提供的內容,您有記憶體洩漏。當您找到引用鏈並且它不在您的程式碼中時,最簡單的方法是……反射器。

圖片說:JournalEntryKeepAlive._keepAliveRoot欄位包含對對象的引用。讓我們進入 Reflector,看看這個傢伙是如何迷上我們的對象的。

這一次很容易,所有的痕跡都會導致NavigationService.MakeJournalEntry()函式,然後是NavigationService.IsContentKeepAlive(). 這裡是:

internal bool IsContentKeepAlive()
{
   bool keepAlive = true;
   DependencyObject dependencyObject = this._bp as DependencyObject;
   if (dependencyObject != null)
   {
       keepAlive = JournalEntry.GetKeepAlive(dependencyObject);
       if (!keepAlive)
       {
           PageFunctionBase base2 = dependencyObject as PageFunctionBase;
           bool flag2 = !this.CanReloadFromUri;
           if ((base2 == null) && flag2)
           {
               keepAlive = true;
           }
       }
   }
   return keepAlive;
}

現在你知道規則了。如果滿足以下條件,對象將保存在記憶體中:

  • 它不是依賴對象;
  • 附加屬性 JournalEntry.KeepAlive 為真;
  • 它不是 PageFunction,不能從 Uri 重新載入。

經過這次調查,可能值得在 MSDN 上閱讀有關JournalEntry.KeepAlive屬性的更多資訊。

這個策略幫助我找到了許多與記憶有關的昆蟲。希望它也能幫助你:)。

PS:如果您在查找此特定洩漏時一直遇到問題,您可以粘貼最少的程式碼範例讓我們重現它並為您提供更正確的答案。

乾杯,安瓦卡

引用自:https://stackoverflow.com/questions/1925052