A WPF window doesn't release the memory after closed

后端 未结 3 657
灰色年华
灰色年华 2021-02-08 20:36

I\'m stilling trying to figure out the answer to this question: https://stackoverflow.com/questions/14379994/wpf-memory-optimization-advice

So I created a test code:

相关标签:
3条回答
  • 2021-02-08 21:07

    Your test code is flawed, see here for my comments on an almost identical scenario.

    Yours is a bit simpler but same comments apply:

    • setting a variable null and calling GC.Collect is not enough. The 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

    In addition your GC.Collect call is not enough to collect objects with finalizers, you need

    GC.Collect(); // find finalizable objects
    GC.WaitForPendingFinalizers(); // wait until finalizers executed
    GC.Collect(); // collect finalized objects
    

    See the linked post for a more complete example, after fixing it I could not reproduce any leaked window instance.

    What are these extra memory being used for and how can we release them?

    Besides the flaws in your test code, by looking at memory consumption you may be looking at the wrong thing. Don't look at memory alone, use debugger tools which can inspect live objects. The .NET runtime will anticipate more allocations and not give memory back to the OS immediately, this is not a leak, the OS is perfectly capable to page out unused memory if the runtime doesn't use it. A leak is only present if it keeps growing if you repeat the operation.

    0 讨论(0)
  • 2021-02-08 21:26

    Based on the answer at https://stackoverflow.com/a/4800489/1711103, you might need to explicitly set your Window's parent property. For example, in your constructor, you can call:

    this.Parent = this;
    
    0 讨论(0)
  • 2021-02-08 21:27

    .NET garbage collector automatically takes care of removing objects which are not referenced any more.Take a look at this MSDN

    0 讨论(0)
提交回复
热议问题