问题
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.
回答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
来源:https://stackoverflow.com/questions/16028427/printticket-dllhost-exe-memory-climbs