我们目前正在寻找应用程序中的一些内存泄漏,当执行一些操作(加载和关闭应用程序中的一个项目)时,我们知道内存总是会增加一点点。
我们已经找到了很多这样的类,但是现在,10+中增长最快的类是(根据我们的工具,ANTS Profiler8.2):
不幸的是,我不知道这是什么,所以我很难找到如何/应该发布什么。
我检查了实例树,但是,它一直与微软的东西有关。
问题是,当我们完成一个项目的“开放/关闭”时,我们会经历很多(大部分)代码。
编辑我们的应用程序的一部分使用dynamic关键字对某些资源,它可以链接。这里的课是不可处理的,我应该和他们做些特别的事吗?
编辑2
我很确定这与我的dynamic相关,似乎C#在使用dynamic时会创建一个缓存。但是目前我不知道为什么它会增长(我总是加载相同的类,而且我将始终拥有完全相同的签名),也不知道如何清除它。
发布于 2017-08-22 22:08:03
今天,通过分析我的应用程序RepoZ中的内存泄漏,我遇到了同样的问题。该工具应该在后台运行,检查Git存储库并定期更新Windows窗口标题。后一个任务必须对"Shell.Application“进行一些COM调用,以找到资源管理器窗口并确定它们当前指向的路径。
通过这样使用dynamic关键字..。
dynamic shell = Activator.CreateInstance(...);
foreach (object window in shell.Windows())
{
var hwnd = window.Hwnd;
...
}..。几个小时后,我就变成了这样的记忆转储:

康布里奇
为了解决这个问题,我编写了一个小小的名为"Combridge“的助手类,负责发布COM对象,并提供对底层COM对象的方法和属性的非常容易的访问。这是非常简单和直接的,这里没有什么特别的。它利用了对COM对象的反射,这就是性能下降的原因(见下文)。
使用它,上面的代码示例如下所示:
using (var shell = new Combridge(Activator.CreateInstance(...)))
{
var windows = shell.InvokeMethod<IEnumerable>("Windows");
foreach (var window in windows)
{
var hwnd = window.GetPropertyValue<long>("Hwnd");
...
}
}您可以看到ExplorerWindowActor文件是如何在RepoZ中使用的。
它并不像使用dynamic那样漂亮,而且在这第一次尝试中性能也越来越差。一个快速的长凳显示如下:
性能
我测试了1000次迭代,每次迭代都处理了10个打开的Explorer窗口。对于每个窗口,将在该COM对象上调用4个方法或属性。所以我们说的是40.000个电话。
持续时间从~2500 to (dynamic)上升到~6000 to (Combridge)。每通电话从0.062ms到0.150ms不等。
,所以这需要大约2.4倍的时间才能完成。
我知道这很重要。但是我的需求没有问题,内存泄漏也没有了。
就是这样--我想和你分享这个故事,希望你也能用这个类(或者它的一个改进版本)走出动态的地狱。
~更新~
10小时后,RepoZ仍然以非常稳定的内存占用运行。

因此,在打开10个资源管理器窗口,每个窗口4个COM调用和整个循环每秒两次时,RepoZ创建了大约72.000 COM实例,并使2.880.000 COM调用的总数没有增加任何内存消耗。
我想我们可以说,dynamic确实带来了这个问题。
发布于 2015-12-06 21:57:38
动态关键字应该很少使用,因为在大多数情况下,可以找到不需要它的解决办法。
根据您的应用程序,最好的建议是仔细考虑是否可以设计解决方案,以避免动态。下面是一些动态的有效用例:https://msdn.microsoft.com/en-us/library/dd264736.aspx
考虑到您确实需要使用dynamic,我建议对代码进行测试,并确定哪些部分是内存消耗最大的部分。实际上,使用动态会增加内存消耗,因为它需要执行所有类型的查找,但是要有内存不足的异常,则需要在许多未知类型中使用大量的动态变量。
在未知类型上调用方法有很多不同的方法,测量和调整瓶颈是可行的。
PS:另外,发布一些代码片段也很有帮助。
https://stackoverflow.com/questions/33080252
复制相似问题