3

好的。我不完全确定原因可能是什么,但我将尝试解释我认为相关的因素,希望有人能提供帮助!我很乐意回答任何可能遗漏的问题。长话短说有问题的代码:

  • 使用 ITextSharp 在一个充满 PDF 的文件夹中检查页数等。
  • 使用 task.factories 进行线程处理(基本上,主子调用“pdf 计数”子,计数子使用 interlocked.add 将页面添加到公共变量。)
  • 我使用非常相似的过程(使用不同的库)对 Tiff 文件执行相同的操作。它似乎没有同样的问题。
  • 如果我重新运行程序而不先关闭它(只是再次计算文件),任务管理器中的内存使用量起初会下降一点,但最终会比上一次迭代更高。似乎有一个上限,但我还没有真正测试过。
  • 程序完成后,处理器使用率恢复正常。

我遇到的问题是,当我执行此操作时,任务管理器中分配给程序的内存会很快变得不成比例地变大(它会上下反弹一些,但在运行此操作时通常在 300-700 mb 之间处理几百个文件)。即使程序“完成”并仅在表单上显示结果,它也继续处于该级别的内存使用情况。查看任务、线程等,当程序“完成”时,这一切似乎都很正常。但似乎某些东西仍然以某种方式存储在某个地方的内存中。

我的模糊理解是垃圾收集应该在子结束时处理任何清理,对吗?甚至尝试做一个简单的 Using 语句,例如:

    Using PDFDocx As PdfReader = New PdfReader(PDFToCount)
        Dim Pges As Integer = PDFDocx.NumberOfPages
        Interlocked.Increment(Pges)
    End Using

似乎根本没有区别。我对托管代码与非托管代码的整体理解充其量是模糊的。这个 DLL 是否会构成非托管代码,如果是这样,这是否是问题所在?任务管理器中的内存分配是否是一种视觉错觉?或者是否有可能像我一样使用任务库导致问题?我意识到这有点模糊,我很乐意填写我能填写的任何信息。

编辑:作为后续,我使用这篇文章http://www.codeproject.com/Articles/42721/Best-Practices-No-5-Detecting-NET-application-memo引导我使用 DebugDiag 并获得结果似乎表明:

Function   clr!CExecutionEngine::ClrVirtualAlloc+4a 
Source Line    
Allocation type   Virtual memory allocation(s) 
Allocation Count   12 allocation(s) 
Allocation Size   1.8 GBytes 
Leak Probability   50% 

负责该问题。根据新信息有什么建议吗?

4

1 回答 1

1

您可以使用 Perfmon 来确定您的 .NET 应用程序是否正在泄漏内存(托管或非托管)。

运行 Perfmon.exe 并添加以下计数器:

  • 进程/私有字节
  • .NET CLR 内存 / # 所有堆中的字节数
  • .NET CLR LocksAndThreads / # 当前逻辑线程

运行你的应用程序一段有代表性的时间并练习它的功能。

如果私有字节在增加但所有堆中的 # 个字节没有增加,则非托管内存正在泄漏。如果两者都在增加,则托管内存正在泄漏。

如果当前逻辑线程的数量超出您的预期,则线程堆栈正在泄漏。

如果Private Bytes以 1MB 的增量周期性地跳跃,并且当前逻辑线程数相应增加,则可能是线程堆栈泄漏的原因。

这里

于 2013-10-13T01:56:58.720 回答