c# - 在 Perfmon 中看到高 "% Time in GC"的原因

标签 c# .net memory memory-management

在 Perf Mon 中监视我们的应用程序时,我注意到当我们的应用程序正在执行长时间运行的进程(在 30 秒到 1.5 分钟之间变化)时,GC 中的时间百分比在 20% 到 60% 之间。这对我来说似乎有点过分。这提出了两个重要问题。

  1. 我说得对吗?
  2. 如何找出路由导致 GC 峰值的原因?

最佳答案

是的,这听起来有点过分。减少 GC 的数量可能是减少应用程序运行时间的最佳步骤(如果这是您的目标)。

较高的“GC 时间百分比”通常是由分配然后丢弃数千或数百万个对象引起的。找出发生了什么的一个好方法是使用内存分析器工具。

Microsoft 提供免费的 CLR Profiler .这将向您显示每个分配,但会使您的应用程序运行速度慢 10-60 倍。您可能需要在较少的输入数据上运行它,以便它可以在合理的时间内完成分析。

一个很棒的商业工具是 SciTech 的 .NET Memory Profiler .这会大大减少运行时开销,并且可以免费试用。通过在进程运行时拍摄多个快照,您可以了解哪些类型的对象被频繁分配(然后被销毁)。

一旦您确定了分配的来源,您就需要检查代码并找出如何减少这些分配。虽然没有万能的答案,但我过去遇到的一些事情包括:

  • String.Split 可以创建数百个短命的小字符串。如果您正在执行大量字符串操作,则可以通过逐个字符遍历来帮助处理字符串。
  • 创建包含数千个小类(例如,大小小于 24 字节)的数组或列表可能会很昂贵;如果这些类可以被视为值类型,则可以(有时)极大地改进将它们更改为结构的事情。
  • 创建数千个小数组会大大增加内存使用量(因为每个数组的开销很小);有时这些可以替换为一个大数组并索引到它的子部分。
  • 拥有大量可终结对象(特别是如果它们没有被释放)会给垃圾收集器带来很大压力;确保您正确处理所有 IDisposable 对象,并注意您自己的类型应该(几乎)never have finalizers .
  • 微软有一篇文章与 Garbage Collection Guidelines以提高性能。

关于c# - 在 Perfmon 中看到高 "% Time in GC"的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1132033/

相关文章:

c# - 如何检查给定进程已创建到 Internet 的哪些连接

c# - 在一个命名空间下的多个子文件夹中重新组合 Razor 组件 - Blazor

c# - 重新创建 Accord.NET DecisionTree 网站示例 - 给定的键不存在于字典中

.net - 如何检查路径中的非法字符?

c# - 无法在 C# 中初始化列表集合?

Android 如何获得设备中的总内存 RAM?

memory - 在游戏中寻找特定的内存位置?

c - 如何以编程方式在 Linux 中获取物理内存地址范围

c# - 如何在没有 Controller 的情况下手动提供 .cshtml 文件?

c# - ASP.NET MVC2 数据访问层