使用特定的DLL库时,内存分配非常高。(memory allocation is very high when using specific DLL library. Maybe. Not sure

编程入门 行业动态 更新时间:2024-10-27 18:31:03
使用特定的DLL库时,内存分配非常高。(memory allocation is very high when using specific DLL library. Maybe. Not sure what to do)

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

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

我遇到的问题是,当我这样做时,分配给任务管理器中程序的内存变得非常快(它在某些情况下上下跳动,但在运行时通常在300-700 mb之间)处理几百个文件)。 即使程序“完成”并且只是在表单上显示结果,它也会继续处于该级别的mem使用状态。 当程序“完成”时,查看任务,线程等似乎都是正常的。 但似乎某种东西仍然存储在某个地方的某个地方。

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

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

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

编辑:作为后续,我使用这篇文章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%

负责这个问题。 基于新信息的任何建议?

Okay. I'm not entirely sure what the cause could even be, but I'm going to try to explain the factors that I think are related and hopefully someone can help! And I'll gladly answer anything else that might be missing. Long story short the code in question:

Uses ITextSharp to check for page counts etc. in a a folder full of PDF's. Uses task.factories for threading (basically a main sub calls the "pdf counting" sub and the counting sub uses interlocked.add to add the pages to a public variable.) I use a very similar process (using a different library) to do the same thing for Tiff files. It doesn't appear to have the same issue. If I rerun the program without closing it first (just counting the files again) the mem usage in task manager will drop a little at first, but eventually ends up higher than the previous iteration. There seems to be a ceiling to that, but I haven't really tested it. Processor usage returns to normal when the program completes.

The problem I've run into is that the memory allocated to the program in the task manager becomes disproportionately large very quickly when I'm doing this (it bounces up and down some, but is usually between 300-700 mb when doing running this process on a few hundred files). It also continues to sit at that level of mem usage even when the program is "done" and just displaying the results on a form. Looking at tasks, threads etc. it all appears to be normal when the program is "done." But it appears something is still being stored in memory somewhere, somehow.

It's my vague understanding that Garbage Collection should deal with any cleanup when the sub ends, right? Even attempting to do a simple Using statement like:

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

seems to make no difference at all. My whole understanding of managed vs. un-managed code is vague at best. Would this DLL constitute un-managed code, and if so, is that somehow the problem? Is the mem allocation in the task manager somehow an optical illusion? Or is it possible that using the task library like I am is causing the problem? I realize this is all a bit vague, and I'll gladly fill in any information I can.

Edit: As a followup, I used this article http://www.codeproject.com/Articles/42721/Best-Practices-No-5-Detecting-NET-application-memo to lead me to using DebugDiag and getting the results that seem to indicate:

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%

is responsible for the issue. Any suggestions based on the new information?

最满意答案

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

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

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

运行您的应用程序一段有代表性的时间并运用其功能。

如果专用字节增加但所有堆中的#字节不增加,则非托管内存正在泄漏。 如果两者都在增加,那么托管内存就会泄漏。

如果当前逻辑线程的数量超出预期,那么线程堆栈就会泄漏。

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

从这里开始 。

You can use Perfmon to determine if your .NET application is leaking memory (managed or unmanaged).

Run Perfmon.exe and add these counters:

Process / Private bytes .NET CLR Memory / # bytes in all heaps .NET CLR LocksAndThreads / # of current logical threads

Run your application for a representative length of time and exercise its functionality.

If Private bytes is increasing but # bytes in all heaps is not, then unmanaged memory is leaking. If both are increasing, then managed memory is leaking.

If the # of current logical threads is increasing beyond what you expect, then thread stacks are leaking.

If Private Bytes is periodically jumping in 1MB increments with a corresponding increase in # of current logical Threads, a thread stack leak is the likely cause.

From here.

更多推荐

本文发布于:2023-08-06 18:25:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1452905.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:分配   内存   DLL   库时   memory

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!