【问题标题】:Huge burst of memory in c# service, what could be the cause?c# 服务中的巨大内存爆裂,可能是什么原因?
【发布时间】:2010-04-26 23:53:50
【问题描述】:

我正在开发一个 c# 服务应用程序,我遇到了这个问题,不知从何而来,也没有明显的原因,进程的内存将在大约 5 秒内从 150mb 攀升到几乎 2gb,然后又回到 150mb。但是我们系统中的任何东西都不应该使用接近那个内存量的任何地方(所以它可能是某个地方的错误)。在某处可能是一个紧的 while true 循环,但当时的 cpu 使用率非常低,所以我想我会寻找其他想法。

现在更奇怪的是,当我为 64 位编译服务时,除了超过 10gb 的内存(其中大部分是分页)之外,还会发生同样的大规模爆发,并且它只会导致计算机及其上运行的所有东西出现很多问题。一段时间后它会关闭,但看起来 Windows 仍然愿意为其提供更多内存。

你有什么想法或工具可以用来找到这个吗? 是的,它有很多日志记录,但是日志中没有任何内容能说明为什么会发生这种情况。

我可以在控制台应用程序模式下运行该服务,所以我的下一个测试将在 Visual Studio 调试器中运行它,看看我是否能找到任何东西。

它只是偶尔发生,但通常在启动后大约 10-20 分钟发生。 在 32 位模式下,它会清理并像往常一样继续。 64位模式它会在一段时间后崩溃并使用愚蠢的内存量。 但我真的很困惑为什么会这样!!!!

编辑:请参阅对 windbg 帖子的赞扬

【问题讨论】:

  • 您能否使用日志记录数据和内存使用突发时间来了解“突发时间”运行的代码是什么?
  • 是的,虽然它看起来像正常活动:(如果我登录了每一个方法,我可能会找到它,但这会有点臃肿>_

标签: c# memory service


【解决方案1】:

您可以尝试使用探查器,例如 CLRProfiler, a free download from MS(非常酷)。它可以分析服务。运行它直到你看到内存峰值,然后停止它并查看堆转储。

【讨论】:

    【解决方案2】:

    你做了很多分配然后你释放。你的记忆会累积起来,直到 GC 启动并在你之后开始清理。在 amd64 平台上,所有结构都更大,因为与 x86 相比,指针、v-tables 和其他结构本身的大小是两倍。

    最简单的解决方案是在调试器下运行应用程序并等待膨胀,然后将其冻结并转储。然后分析转储:

    .loadby sos mscorwks
    !dumpheap -stat
    

    您的泄漏类型将位于列表顶部,并且分配很多。这与您用于分析内存泄漏的技术相同,只是内存在技术上可能没有泄漏,请参阅CLR Memory Leak

    【讨论】:

    • 我现在正在尝试,如何让 windbg 不会在第一次机会异常时停止并一直运行直到我说暂停?
    • sxd 。例如。 sxd avsxd ehsxd clr。停止时将打印要使用的异常类型。
    • 好吧,它目前是 2gb 的内存,我已经停止它,运行这些命令,这是我的问题:000007fef9a4ec90 74179 1895994904 System.String 74179 个 System.Strings 实例及其消耗 1.8gb ram,我该如何进一步缩小范围?
    • 当我执行 !gcroot 命令并传递 000007fef9a4ec90 时,什么都找不到,它显示“请注意 000007fef9a4ec90 不是有效对象”
    • 好的,这非常有帮助,我现在找到了问题所在!我将查看代码以找出导致它的原因,非常感谢!
    【解决方案3】:

    听起来您可能正在执行字符串连接而不是使用 StringBuilder?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 2016-10-27
      • 2017-02-22
      • 2023-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多