0

I'm using PrintTickets to print a large number of WPF objects and things are printing fine. We do have a situation that has been reported where the program is using a ton of the dllhost.exe memory and climbs until the machine eventually crashes. I've narrowed it down to creating a PrintTicket and the printqueue.getprintcapabilitiesasxml(). Each time these are called it jumps the memory usage of the dllhost.exe each time by sometimes 3+ MB. Can anyone tell me either how to avoid this if possible or if there is a way to clear it after i know it is being used?

Update: I've created a project with simple this code.

for (int i = 0; i < 100; i++)
{
    using (System.Printing.PrintQueue pQueuePrnt = 
    new LocalPrintServer().GetPrintQueue("HP LaserJet 9050 PCL 5"))
    {
        using (MemoryStream printerCapXmlStream = pQueuePrnt.GetPrintCapabilitiesAsXml())
        {
            Console.WriteLine(printerCapXmlStream.Length);
        }
    }
}

This will result in almost 60 MB in the dllhost.exe that will never go away.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
Bob Allen
  • 1
  • 1

1 Answers1

1

Any time you see unexplained memory increases, the first thing you should suspect is that your code is leaking memory somewhere. Check all of the functions you call, trace their return values, and make sure that you are disposing of them all when you are finished with them.

You say that you've narrowed it down to the call to PrintQueue.GetPrintCapabilitiesAsXml. That's a good start. So let's check the documentation for that method to see what it returns. Ah, it returns

A MemoryStream specifying the printer's capabilities

So now we need to find out what, exactly, a MemoryStream is. In particular, we need to know if it implements the IDisposable interface and therefore needs to be disposed by our code. According to the documentation, it does, because MemoryStream inherits from Stream.

Presumably, your code is retrieving all of these new MemoryStream objects and then letting them leak their unmanaged resources. You need to either call the Dispose method explicitly for each object, or wrap their retrieval and use in a using statement; e.g.

using (MemoryStream ms = PrintQueue.GetPrintCapabilitiesAsXml())
{
    ms.DoSomething();
    // ...
} // the object is automatically disposed here
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I'm actually doing this already. Its immediately adding memory to the dllhost.exe as soon as it hist this line and it never goes away. I can even shut down the program and restart it and it picks up in the dllhost.exe memory level where it left off. This also does the same thing when i create a PrintTicket. Once i new up a PrintTicket it will do the same thing by adding memory usage to the dllhost and never goes away. – Bob Allen Apr 16 '13 at 14:10