【问题标题】:Hitting a memory limit slows down the .Net application达到内存限制会减慢 .Net 应用程序的速度
【发布时间】:2011-02-15 14:25:18
【问题描述】:

我们有一个在 64 位 Windows 服务器上运行的 64 位 C#/.Net3.0 应用程序。应用程序有时会使用大量可用内存。在某些情况下,应用程序停止分配额外的内存并显着减慢(慢 500 倍以上)。当我从任务管理器检查内存时,使用的内存量几乎没有变化。应用程序继续运行非常缓慢,并且永远不会出现内存不足异常。 有任何想法吗?让我知道是否需要更多数据。

【问题讨论】:

  • 检查垃圾收集器是否正在运行...
  • 检查CPU温度是否过高

标签: c# .net performance memory-management


【解决方案1】:

你可以试试enabling server mode for the Garbage Collector。默认情况下,所有 .NET 应用程序都在工作站模式下运行,在该模式下 GC 会尝试在保持应用程序运行的同时进行扫描。如果您打开服务器模式,它会暂时停止应用程序,以便它可以更快地释放内存(很多),并且它还为每个处理器/内核使用不同的堆。

大多数服务器应用在使用 GC 服务器模式时都会看到性能提升,尤其是在它们分配大量内存的情况下。不利的一面是,当您的应用程序开始耗尽内存时(直到 GC 完成),它基本上会停止。

* 要启用此模式,请将以下内容插入您的app.configweb.config

<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

【讨论】:

  • 我很难找到如何在网络上为垃圾收集器设置服务器模式。如果您知道可以添加它来回答吗?
  • @derdo:在链接中有解释,但我已经在这个答案中转载了。
  • GC 服务器模式对我们帮助很大。我们还通过分析器确定了我们每秒分配许多 GB 内存的位置。我们也在这方面做了一些改进,最终克服了这个问题。感谢大家的回复。
【解决方案2】:

当您达到物理内存限制时,操作系统将开始分页(即将内存写入磁盘)。这确实会导致您看到的那种减速。

解决方案?

  • 添加更多内存 - 这只会在您达到新的内存限制之前有所帮助
  • 重写您的应用程序以使用更少的内存
  • 找出是否存在内存泄漏并修复它

如果内存不是问题,也许您的应用程序对 CPU 的影响很大?你看到 CPU 接近 100% 了吗?如果是这样,请检查一遍又一遍地迭代的大型集合。

【讨论】:

  • 从问题看来,有足够的物理内存可用,但应用程序由于某种原因没有使用它...
  • 不,cpu 没有得到充分利用,在一台机器上它使用 2.8-3GB 的 8GB 内存,在另一台机器上使用 7-8GB 的​​ 16GB。
【解决方案3】:

【讨论】:

  • OP 声明 64 位操作系统和 64 位应用程序。
  • 限制仍然适用...“...在 64 位 Windows 操作系统上运行 64 位托管应用程序时。”
  • 在某些方面限制更加严格,因为 64 位应用程序中的引用需要 8 个字节,而 32 位应用程序中只有 4 个字节......换句话说,你只能有 1/ 2 64 位应用程序中的引用次数比 32 位应用程序中的引用次数...
  • 我们没有那么大的对象。我们只有很多。我们创建和处置许多小对象(双精度数组)。
【解决方案4】:

其他答案中提到了很多好东西。不过,无论如何,我都会掏出两便士(或美分 - 取决于你来自哪里!)。

假设这确实是一个 64 位进程,如您所说,这里有一些调查途径...

您正在检查哪些内存使用情况?内存使用或 VMem 大小? VMem 大小是真正重要的,因为它适用于分页和非分页内存。如果这两个数字相差太远,那么内存使用确实是导致速度变慢的原因。

当事情开始变慢时,整个服务器的实际内存使用量是多少?减速是否也适用于其他应用程序?如果是这样,那么您可能有内核内存问题 - 这可能是由于大量磁盘访问和低级资源使用(例如,创建 20000 个互斥体,或通过使用 Win32 HBitmaps 的代码加载几千个位图)。您可以在任务管理器上获得一些指示(尽管 Windows 2003 的版本比 2008 的版本直接提供更多信息)。

当您说应用程序明显变慢时,您怎么知道?你在使用海量的字典或列表吗?难道不仅仅是内部数据结构变得如此之大以至于使任何内部算法正在执行的工作变得复杂吗?当您处理大量数据时,某些算法可能会开始变慢几个数量级。

应用程序在全速运行时的 CPU 负载是多少?实际上和减速发生时一样吗?如果 CPU 使用量随着内存使用量的增加而减少,那么这意味着无论它在做什么都需要更长的时间来完成操作系统,这意味着它可能会给操作系统带来过多的负载。如果 CPU 负载没有差异,那么我的猜测是内部数据结构变得如此之大以至于会减慢您的算法。

我肯定会考虑在应用程序上运行 Perfmon - 从一些 .Net 和本机内存计数器、缓存命中和未命中以及磁盘队列长度开始。在应用程序从启动到它开始像哮喘乌龟一样运行的整个过程中运行它,您可能也会从中得到一些线索。

【讨论】:

    【解决方案5】:

    浏览其他答案后,我想说有很多好主意。这是我没看到的:

    获取内存分析器,例如 SciTech 的 MemProfiler。它会告诉你分配了什么,分配了什么,它会告诉你整个切片和骰子。

    它还有视频教程,以防您不知道如何使用它。就我而言,我发现我没有使用 IDisposable 实例(...)

    【讨论】:

      猜你喜欢
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 2021-05-28
      • 2019-11-22
      相关资源
      最近更新 更多