简体   繁体   中英

Disposing and resource management in C#

I use BackGroundWorker and ProgressBar .

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;
}

In MyMethod I use Dispose() method for necessary resources.

  • While my app is start up, it uses ~10 000 K memory.
  • While my app is running, it uses between ~40 000 k - ~ 70 000k memory.
  • When operation is completed, it uses ~30 000 k memory.

How can I catch what is using 30 000 k - 10 000 k=~20 000 k memory?

Calling Dispose() in .Net doesn't immediately collect the memory - it leaves it until it's not busy doing something else.

Basically it hasn't collected that 20MB because that wasted memory isn't slowing it down yet. Your machine probably has GB free, why stop and tidy up when there's still plenty of space?

Call GC.Collect() to force it, but note that this is usually slower than leaving .Net to do its thing - .Net is quite good at only collecting when it has to, as long as you've disposed of the resource.

You can try VMMap from Sysinternals . it's a free MS-tool that lets you analyse the memory-usage of a process.

If you are not very familiar with profiling an app, try this great video:

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

It has a part about memory-analysis. As already written, don't count too much on values given by taskmanager and ProcessInfo. Because GC does not work immediately, there is a good chance that deallocation is not done yet because of efficiency.

How can I catch what is using 30 000 k - 10 000 k=~20 000 k memory?

By using a memory Profiler. But consider:

  • looking at a simple metric (Taskmanager) for 'memory consumption' is close to meaningless
  • you probably don't have a problem
  • it is unrelated to the Bgw

And for good measure:

  • Your Completed handler is not checking for errors. Could lead to nasty bugs.

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

如果您想知道占用此空间的内容,则必须使用Memory Profiler,例如ProfileSharp

You could use ANTS memory profiler to have a look what is sitting in memory. Its a great tool for hunting for memory leaks etc - download a trial here: http://www.red-gate.com/products/ants_memory_profiler/index.htm

Is it possible that in MyMethod() you have perhaps hooked up an event from an external class which is not being unhooked up when you are complete with the method?

But as Keith mentioned, objects remain in memory until the Garbage collector runs. As long as they are properly disposed of they will be released when necessary. Even calling GC.Collect() does not guarantee that the Garbage collector will run immediately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM