【问题标题】:Memory leakage in c# windows service multithreading applicationc# windows服务多线程应用程序中的内存泄漏
【发布时间】:2009-08-26 13:24:29
【问题描述】:

我有一个用于索引目的的 Windows 服务多线程应用程序,它有六个线程。除了内存泄漏外,它工作正常。实际上,当服务启动时,服务消耗了 12,584kb 内存,一段时间后它消耗了 61,584kb 内存。但是在索引过程完成后,它不会释放内存。 我需要它在索引完成后回到它以前的位置,也就是说它应该占用它开始的内存,例如在这种情况下为 12,584kb。 我使用了垃圾收集,但它没有做我想要的。

谁能帮帮我?

【问题讨论】:

  • 你能分享一些索引功能的代码吗?
  • 你是如何测量内存的?毕竟,考虑到 .Net 内存管理器的工作方式,perfmon 是唯一可靠的方法。

标签: c# windows multithreading service


【解决方案1】:

第一个建议是使用内存分析器。我一直对Red Gate's ANTS profiler 很满意,这将有助于识别哪些 对象正在泄漏(如果有)。

请记住,可能会在各处进行首次初始化,因此您可能希望随着时间的推移对其进行跟踪

【讨论】:

    【解决方案2】:

    .NET 不会释放内存来满足盯着任务管理器的人。分配内存是昂贵的。 CLR 旨在谨慎地执行此操作,并尽可能长时间地保留它分配的任何内存。可以这样想——当你不使用它的一半时,拥有 4gb 的内存有什么意义?

    除非您真的知道您有内存泄漏(例如,您的应用在正常运行两天后崩溃),否则让我给您一条建议...关闭任务管理器。在您知道需要之前不要优化内存。放松,伙计。一切都很好。

    【讨论】:

    • +1 表示 CRL 行为。然而,仅仅等待崩溃似乎不是要走的路。 .NET 内存分析器应该能够显示内存是否只是没有释放到系统,或者是否真的有对象泄漏(至少根据我的经验,最常见的情况是:忘记清除某些集合)
    • 在确定有问题之前等待应用崩溃并没有错。不过,您的内存分析器会让您更容易入睡。
    【解决方案3】:

    61 MB 听起来并不奇怪。您将需要让服务运行一段时间并监控其内存使用量是否呈上升趋势。如果您看到应用程序在某个值上趋于平稳,则可能没有什么可担心的。

    【讨论】:

    • 我同意。高内存消耗与内存泄漏不同。
    【解决方案4】:

    我完全同意 Will - 但是我提供 2 条小建议:

    1. 不要使用 GC.Collect。相信我,您不会通过这样做来改进 CLR 的垃圾收集算法。事实上,准备好收集但由于某种原因无法收集的对象将被移至第 2 层,在那里它们将不得不等待更长的时间才能被收集(从而可能使任何泄漏变得更糟!)
    2. 检查您的代码中是否已创建某种类型的流(通常是 MemoryStream)并验证流是否正确关闭(最好在“finally”块中)

    【讨论】:

      【解决方案5】:

      这里我使用“log4net-1.2.10”处理异常,“Lucene.net-2.1.0.3”用于索引,这是一个“IndexWriter”类,用于在索引中添加文档或从索引中删除文档。 锁(对象) {
      indexWriter.AddDocument(document);// "IndexWriter" 类的 indexWriter 对象。
      }。 我们也使用微软消息队列来检索消息。

      【讨论】:

        【解决方案6】:

        在将应用程序从 STA 更改为 MTA 之前,我遇到了同样的问题:

        [MTA线程] public static void Main()

        而不是 [STA线程] public static void Main()

        (我用过 Red Gate 的 ANTS profiler...)

        【讨论】:

          猜你喜欢
          • 2012-06-14
          • 1970-01-01
          • 2015-08-14
          • 2010-10-13
          • 2013-04-16
          • 1970-01-01
          • 2018-07-14
          • 1970-01-01
          • 2014-04-19
          相关资源
          最近更新 更多