C#中的处理和资源管理

时间:2010-09-16 07:54:00

标签: c# memory-management dispose

我使用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 000 K内存。
  • 当我的应用程序运行时,它使用~40 000 k - ~70 000k记忆。
  • 操作完成后,使用~30 000 k内存。

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

6 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

如果您对分析应用不太熟悉,请尝试以下视频:

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

它有关于记忆分析的部分。如前所述,不要对taskmanager和ProcessInfo给出的值进行太多计算。由于GC不能立即起作用,因此效率很可能尚未完成释放。

答案 2 :(得分:1)

  

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

使用内存Profiler。但请考虑:

  • 查看“内存消耗”的简单指标(Taskmanager)接近无意义
  • 你可能没有问题
  • 与Bgw
  • 无关

好的衡量标准:

  • 您的已完成处理程序未检查错误。可能导致讨厌的错误。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

如果您想知道占用此空间的内容,您必须使用内存分析器,例如ProfileSharp

答案 5 :(得分:0)

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

在MyMethod()中你是否有可能从一个外部类中挂起一个事件,当你完成该方法时它没有被解开?

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