次のコード スニペットは、XPS ファイルを開くときのメモリ リークを示しています。それを実行してタスク マネージャーを監視すると、アプリが終了するまで、タスク マネージャーが大きくなり、メモリが解放されません。
'***** コンソール アプリケーションの開始。
Module Main
Const DefaultTestFilePath As String = "D:\Test.xps"
Const DefaultLoopRuns As Integer = 1000
Public Sub Main(ByVal Args As String())
Dim PathToTestXps As String = DefaultTestFilePath
Dim NumberOfLoops As Integer = DefaultLoopRuns
If (Args.Count >= 1) Then PathToTestXps = Args(0)
If (Args.Count >= 2) Then NumberOfLoops = CInt(Args(1))
Console.Clear()
Console.WriteLine("Start - {0}", GC.GetTotalMemory(True))
For LoopCount As Integer = 1 To NumberOfLoops
Console.CursorLeft = 0
Console.Write("Loop {0:d5}", LoopCount)
' The more complex the XPS document and the more loops, the more memory is lost.
Using XPSItem As New Windows.Xps.Packaging.XpsDocument(PathToTestXps, System.IO.FileAccess.Read)
Dim FixedDocSequence As Windows.Documents.FixedDocumentSequence
' This line leaks a chunk of memory each time, when commented out it does not.
FixedDocSequence = XPSItem.GetFixedDocumentSequence
End Using
Next
Console.WriteLine()
GC.Collect() ' This line has no effect, I think the memory that has leaked is unmanaged (C++ XPS internals).
Console.WriteLine("Complete - {0}", GC.GetTotalMemory(True))
Console.WriteLine("Loop complete but memory not released, will release when app exits (press a key to exit).")
Console.ReadKey()
End Sub
End Module
'***** コンソール アプリケーションは終了します。
1000 回ループする理由は、私のコードが大量のファイルを処理し、すぐにメモリ リークを起こし、OutOfMemoryException を強制するためです。ガベージ コレクションの強制は機能しません (XPS 内部の管理されていないメモリ チャンクであると思われます)。
コードはもともと別のスレッドとクラスにありましたが、これに単純化されました。
どんな助けでも大歓迎です。
ライアン