Window object not released after being closed, even after GC Collect and WaitForPendingFinalizers?

前端 未结 1 857
别那么骄傲
别那么骄傲 2021-01-27 10:24

This is a simple test application to help understand WPF memory usage. They key thing I want to understand is why MainWindow is still referenced and it\'s memory no

相关标签:
1条回答
  • 2021-01-27 10:56

    This test is making several mistakes, also explained here

    • you are taking the second snapshot while the MainWindow variable is still on the stack frame. JIT is allowed to optimize your assignment to window = null; away because it can clearly see the variable is not used anymore afterwards. Furthermore GC reporting of stack frames is not exact (with respect to your source), there may be hidden copies on the stack. Move the test code into a separate method which you return from, to make sure no references to MainWindow are left on the stack. (Technically not necessary after fixing the next point, but I'm mentioning it for completeness so people understand that point when writing GC tests.)
    • you are not giving the multithreaded WPF rendering engine time to clean up, closing and forcing GC is not enough to synchronize with the rendering engine to clean up its resources
    • you are leaving StartupUri="MainWindow.xaml" in the app, remove it to make testing with the fixed code simpler

    The correct way to perform your test is to start a DispatcherTimer and take the second snapshot there, for me the MainWindow is gone then.

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // *** SNAPSHOT 1 ***
    
        ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
    
        RunTest();
    
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    
        new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, Callback, Dispatcher).Start();
    }
    
    private void Callback(object sender, EventArgs e)
    {
        // *** SNAPSHOT 2 ***
    }
    
    private static void RunTest()
    {
        MainWindow window = new MainWindow();
        window.Show();
        window.Close();
        window = null;
    }
    
    0 讨论(0)
提交回复
热议问题