首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内存溢出:具有越来越多的Microsoft.CSharp.RuntimeBinder.Semantics

内存溢出:具有越来越多的Microsoft.CSharp.RuntimeBinder.Semantics
EN

Stack Overflow用户
提问于 2015-10-12 11:42:15
回答 2查看 2.3K关注 0票数 14

我们目前正在寻找应用程序中的一些内存泄漏,当执行一些操作(加载和关闭应用程序中的一个项目)时,我们知道内存总是会增加一点点。

我们已经找到了很多这样的类,但是现在,10+中增长最快的类是(根据我们的工具,ANTS Profiler8.2):

  • Microsoft.CSharp.RuntimeBinder.Semantics.SYMTBL+Key
  • Microsoft.CSharp.RuntimeBinder.Semantics.LocalVariableSymbol
  • Microsoft.CSharp.RuntimeBinder.Semantics.CONSTVAL
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCONSTANT
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCLASS
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRTYPEOF
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRLIST
  • Microsoft.CSharp.RuntimeBinder.Semantics.MethWithInst
  • Microsoft.CSharp.RuntimeBinder.Semantics.CMemberLookupResults
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRMEMGRP
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRCALL
  • Microsoft.CSharp.RuntimeBinder.Semantics.EXPRWRAP
  • Microsoft.CSharp.RuntimeBinder.Semantics.AggregateDeclaration
  • Microsoft.CSharp.RuntimeBinder.Semantics.Scope

不幸的是,我不知道这是什么,所以我很难找到如何/应该发布什么。

我检查了实例树,但是,它一直与微软的东西有关。

问题是,当我们完成一个项目的“开放/关闭”时,我们会经历很多(大部分)代码。

编辑我们的应用程序的一部分使用dynamic关键字对某些资源,它可以链接。这里的课是不可处理的,我应该和他们做些特别的事吗?

编辑2

我很确定这与我的dynamic相关,似乎C#在使用dynamic时会创建一个缓存。但是目前我不知道为什么它会增长(我总是加载相同的类,而且我将始终拥有完全相同的签名),也不知道如何清除它。

EN

回答 2

Stack Overflow用户

发布于 2017-08-22 22:08:03

今天,通过分析我的应用程序RepoZ中的内存泄漏,我遇到了同样的问题。该工具应该在后台运行,检查Git存储库并定期更新Windows窗口标题。后一个任务必须对"Shell.Application“进行一些COM调用,以找到资源管理器窗口并确定它们当前指向的路径。

通过这样使用dynamic关键字..。

代码语言:javascript
复制
dynamic shell = Activator.CreateInstance(...);
foreach (object window in shell.Windows())
{ 
    var hwnd = window.Hwnd;
    ...
}

..。几个小时后,我就变成了这样的记忆转储:

康布里奇

为了解决这个问题,我编写了一个小小的名为"Combridge“的助手类,负责发布COM对象,并提供对底层COM对象的方法和属性的非常容易的访问。这是非常简单和直接的,这里没有什么特别的。它利用了对COM对象的反射,这就是性能下降的原因(见下文)。

使用它,上面的代码示例如下所示:

代码语言:javascript
复制
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确实带来了这个问题。

票数 5
EN

Stack Overflow用户

发布于 2015-12-06 21:57:38

动态关键字应该很少使用,因为在大多数情况下,可以找到不需要它的解决办法。

根据您的应用程序,最好的建议是仔细考虑是否可以设计解决方案,以避免动态。下面是一些动态的有效用例:https://msdn.microsoft.com/en-us/library/dd264736.aspx

考虑到您确实需要使用dynamic,我建议对代码进行测试,并确定哪些部分是内存消耗最大的部分。实际上,使用动态会增加内存消耗,因为它需要执行所有类型的查找,但是要有内存不足的异常,则需要在许多未知类型中使用大量的动态变量。

在未知类型上调用方法有很多不同的方法,测量和调整瓶颈是可行的。

PS:另外,发布一些代码片段也很有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33080252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档