简体   繁体   中英

WPF PrintVisual Memory Leak

I am having a bit of an issue when using PrintDialog.PrintVisual , as it seems to be causing a memory leak.

In this application I create a WPF control which is only used for printing, it is never shown on the screen. Here is an example of the code:

Calling the print

public void PrintDocument()
{
   PrintUserControl printControl = new PrintUserControl();
   printControl.Print();
}

The Print User Control

public class PrintUserControl
{
    public PrintUserControl()
    {
       InitializeComponent();
    }

    public void Print()
    {
        const double width = 5.8 * 96;
        const double height = 8.3 * 96;

        this.Measure(new Size(width, height));
        this.Arrange(new Rect(new Size(width, height)));
        this.UpdateLayout();

        var dlg = new PrintDialog();

        PageMediaSize pageMedia = new PageMediaSize(PageMediaSizeName.ISOA5);
        dlg.PrintTicket.PageMediaSize = pageMedia;
        dlg.PrintVisual(this, "FooDocument");
    }
}

I have profiled this application and when calling the PrintUserControl.Print method there appears to be memory leak, many instances of LayoutEventList+ListItem and ConditionalWeakTable . If I comment out the PrintUserControl.Print method, then there are no leaks, but obviuosly nothing prints.

Am I not disposing something I should be?

So they've been properly cleared up, but GC hasn't run and won't until it decides it needs to. (This is usually when the machine gets short of memory.)

This is basically how .NET works, and in general how Garbage Collected languages work.

The advantage is you don't have to worry about whether to use Free or delete, or memory leaks where you forget to use either; the disadvantage is that your process uses more memory until the Collector gets around to cleaning stuff up.

It won't run until there is a need to clean stuff up as otherwise it is taking resources (CPU etc) from your app when they really aren't needed elsewhere. It will only do that when some conditions apply, such as low system memory available. I believe that the circumstances in which GC decides to run are 'an implementation detail' and should not be relied on as they will change between .NET versions.

A reasonable like is this one from MSDN . You can also search on 'non-deterministic finalisation', which had a number of people excercised when .NET was in iuts original beta.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM