【问题标题】:Disposing and resource management in C#C# 中的处理和资源管理
【发布时间】:2010-09-16 07:53:59
【问题描述】:

我使用BackGroundWorkerProgressBar

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;

    e.Result = MyMethod((int)e.Argument, worker, e);

}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    tStripStatus.Text = "operation Ended.";
    tStripStatus.ForeColor = Color.Green;
}

MyMethod 中,我使用Dispose() 方法获取必要的资源。

  • 当我的应用程序启动时,它使用 ~10 000K 内存。
  • 当我的应用程序运行时,它使用了 ~40 000 k - ~ 70 000k 内存。
  • 操作完成后,它使用约 30 000 k 内存。

如何捕获正在使用 30 000 k - 10 000 k=~20 000 k 内存的内容?

【问题讨论】:

  • 如果您想分析为什么它可能占用资源,您应该发布 MyMethod。但可能只是GC还没有收集到内存。
  • @Albin,MyMethod 很难理解。我只是想知道,其他人和专业人士使用哪些技术来解决资源问题。
  • 您如何确定您的应用程序实际使用了多少内存?如果您只查看任务管理器中的 “内存(私有工作集)” 列,那并不能告诉您任何信息。
  • @Timwi:我使用“内存(私有工作集)”列,并运行应用程序。通过此列中的值,我获得了在不同阶段使用我的应用程序的内存数量。但据我现在理解,这是错误的方式。

标签: c# memory-management dispose


【解决方案1】:

在 .Net 中调用 Dispose() 不会立即收集内存 - 它会保留它,直到它不忙于做其他事情。

基本上它没有收集到 20MB,因为浪费的内存还没有减慢它的速度。您的机器可能有 GB 空闲空间,为什么在还有足够空间的时候停下来整理一下?

调用GC.Collect() 强制它,但请注意,这通常比离开 .Net 来做它的事情要慢 - .Net 非常擅长只在需要时收集,只要你已经处理了资源.

【讨论】:

  • 您会经常注意到,在您释放资源后,您的应用程序的内存使用量并没有减少 - .NET 将管理您的内存并决定何时释放或分配更多内存
  • Dispose 与内存消耗无关。
【解决方案2】:

我如何捕捉正在使用 30 000 k - 10 000 k=~20 000 k 内存的内容?

通过使用内存分析器。但请考虑:

  • 查看“内存消耗”的简单指标(任务管理器)几乎毫无意义
  • 你可能没有问题
  • 它与 Bgw 无关

为了更好的衡量:

  • 您的 Completed 处理程序未检查错误。可能会导致严重的错误。

【讨论】:

    【解决方案3】:

    您可以从Sysinternals 尝试 VMMap。它是一个免费的 MS 工具,可让您分析进程的内存使用情况。

    如果您对应用程序的分析不是很熟悉,请观看这​​个精彩的视频:

    http://www.microsoftpdc.com/2009/CL11

    它有一部分是关于内存分析的。正如已经写过的,不要太依赖 taskmanager 和 ProcessInfo 给出的值。由于 GC 不会立即工作,因此很有可能由于效率原因尚未完成释放。

    【讨论】:

      【解决方案4】:

      CLR 负责内存管理,因此如果您不使用代码中的外部资源,则内存将在垃圾收集器运行时被释放。

      【讨论】:

        【解决方案5】:

        如果你想知道什么占用了这个空间,你必须使用内存分析器,比如ProfileSharp

        【讨论】:

          【解决方案6】:

          您可以使用 ANTS 内存分析器来查看内存中的内容。它是寻找内存泄漏等的好工具 - 在此处下载试用版:http://www.red-gate.com/products/ants_memory_profiler/index.htm

          是否有可能在 MyMethod() 中,您可能从外部类中连接了一个事件,当您完成该方法时,该事件没有被取消连接?

          但正如 Keith 所说,在垃圾收集器运行之前,对象会一直保留在内存中。只要它们被妥善处理,它们就会在必要时被释放。即使调用 GC.Collect() 也不能保证垃圾收集器会立即运行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-12-14
            • 1970-01-01
            • 1970-01-01
            • 2018-06-05
            • 2010-09-16
            • 1970-01-01
            • 1970-01-01
            • 2011-01-18
            相关资源
            最近更新 更多