开发者

How to force garbage collector to run?

Interviewer asked开发者_运维百科 me about this today ...is there an answer ?


System.GC.Collect() forces garbage collector to run. This is not recommended but can be used if situations arise.


It is not recommended to call gc explicitly, but if you call

GC.Collect();
GC.WaitForPendingFinalizers();

It will call GC explicitly throughout your code, don't forget to call GC.WaitForPendingFinalizers(); after GC.Collect().


GC.Collect() 

from MDSN,

Use this method to try to reclaim all memory that is inaccessible.

All objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected. Use this method to force the system to try to reclaim the maximum amount of available memory.


GC.Collect()


GC.Collect();

Keep in mind, though, that the Garbage Collector might not always clean up what you expect...


You do not want to force the garbage collector to run.

However, if you ever did (as a purely academic exercise, of course):

GC.Collect()


I think that .Net Framework does this automatically but just in case. First, make sure to select what you want to erase, and then call the garbage collector:

randomClass object1 = new randomClass
...
...
// Give a null value to the code you want to delete
object1 = null;
// Then call the garbage collector to erase what you gave the null value
GC.Collect();

I think that's it.. Hope I help someone.


Since I'm too low reputation to comment, I will post this as an answer since it saved me after hours of struggling and it may help somebody else:

As most people state GC.Collect(); is NOT recommended to do this normally, except in edge cases. As an example of this running garbage collection was exactly the solution to my scenario.

My program runs a long running operation on a file in a thread and afterwards deletes the file from the main thread. However: when the file operation throws an exception .NET does NOT release the filelock until the garbage is actually collected, EVEN when the long running task is encapsulated in a using statement. Therefore the program has to force garbage collection before attempting to delete the file.

In code:

var returnvalue = 0;
using (var t = Task.Run(() => TheTask(args, returnvalue)))
{
  // TheTask() opens a file and then throws an exception. The exception itself is handled within the task so it does return a result (the errorcode)
  returnvalue = t.Result;
}

//Even though at this point the Thread is closed the file is not released untill garbage is collected
System.GC.Collect();
DeleteLockedFile();


Here is an alternate suggestion. Leave server GC enabled as you have done. Then based on a user defined setting force GC to run if app memory goes above a certain threshold that you determine as the critical level.

Mind you if you follow this path you are effectively stating that you have better knowledge of when garbage collection should run that the CLR does. Most often than not I've found that the CLR does a better job on its own than when we interfere with it.

Code to check memory usage and run GC across either all generations or a specified generation

    long UsedMemory;
//UsedMemory = GC.GetTotalMemory(false); // Not as reliable
UsedMemory = System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64;
if (UsedMemory > 1073741824) // One GB in bytes 1 X 1024 X 1024 X 1024
{
    GC.Collect(); // Collect all generations
    //GC.Collect(2,GCCollectionMode.Forced);; Or collect a specific generation and force it to run now
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜