title: Advanced debugging advice in WPF GarbageCollection
body: <p><strong>Situation</strong></p>
  
  <p>We are running a large WPF application which does not release memory for quite some time. It is not a real memory leak, as the memory will be released eventually. I know that normally, this would not be considered to be a problem. Unfortunately it becomes a performance issue in conjunction with the WPF commanding infrastructure. See below for a more detailed description.</p>
  
  <p><strong>Findings</strong></p>
  
  <p>We have automated tests, that perform typical use cases. Some cases are working fine and are releasing the memory in time. Others are hogging the memory until the client is minimized, a new Window is opened or some other conditions occur that triggers a Gen2 collection.</p>
  
  <p>•   With ANTS we see, that the objects do not have a GC Root, but a lot of references to other objects that require finalization. </p>
  
  <p>•   WinDbg does not show any objects to be ready for finalization.</p>
  
  <p>•   Running several <code>GC.Collect()</code>, <code>GC.WaitForPendingFinalizers()</code> completely frees the memory.</p>
  
  <p>•   We know which UI action causes the high memory condition, but we could not identify any suspicious code.</p>
  
  <p><strong>Question</strong></p>
  
  <p>We would appreciate any advice on debugging such a problem. </p>
  
  <hr>
  
  <p><strong>WPF CommandManager Background</strong> </p>
  
  <p>The WPF CommandManager holds private collection of WeakReferences (<code>_requerySuggestedHandlers</code>) for raising the <code>CanExecuteChanged</code> Event. Handling <code>CanExecuteChanged</code> is quite costly (especially finding the EventRoute for <code>CanExecute</code>, which apparently is a <code>RoutedEvent</code>). Anytime the CommandManager feels like requerying if commands can be executed, it iterates through this collection and calls the <code>CanExecuteChanged</code> event on the respective command sources.</p>
  
  <p>The WeakReferences are not removed from that collection as long as there is a GC handle for the referenced object. While the object has not been collected, the CommandHelper keeps processing <code>CanExecute</code> events for these elements (ButtonBase or MenuItems). In case there is a lot of garbage (as in our case),  this can result in an extremely large number of calls the CanExecute event handlers, which causes the application to be really laggy.</p>