How to force garbage collector to run?
Asked Answered
B

10

193

Interviewer asked me about this today ...is there an answer ?

Bobbe answered 23/11, 2010 at 15:2 Comment(7)
This question has good info about why you shouldn't do that though: #119133Rate
why are you telling like thisBobbe
The How part is far less important than the Why (not) to call it question.Hearken
@Jason - Maybe the interviewer didn't want to hear the solution, rather get Andrew's knowledge and reasoning against doing it, then this question could effectively make sense.Swaggering
@Swaggering It is still a terrible question. Someone with the knowledge in a stressful interview would not realise it is a trick question, or think to supply additional info. Then the question doesn't help the interviewer distinguish between someone with the knowledge or someone without it. So the question is still terrible.Aphra
see also #478667Tamarah
"When do you force garbage collection?" sounds like a good interview question to me ("How": not so much). Beginner: I dunno. Intermediate: Never. Expert: When you write a test for memory leaks.Intendancy
M
232

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

Mauchi answered 23/11, 2010 at 15:5 Comment(3)
Why is it not recommended?Fuegian
GC.Collect() is expensive to run. Doing it more than necessary is inadvisable. The code for when it should be called is well written. You should normally only self collect in specialized edge cases. https://mcmap.net/q/30325/-when-is-it-acceptable-to-call-gc-collectWore
One valid place to run it, is just before a perf timing run during testing.Ornie
L
229

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().

Lowland answered 23/11, 2010 at 15:4 Comment(4)
WaitForPendingFinalizers doesn't necessarily give "better performance": it simply blocks until all objects in the finalisation queue have been finalised (objects which might have been put there by your previous call to Collect). If you want a chance for those objects to be collected then you need another call to Collect after calling WaitForPendingFinalizers.Gallicanism
Since one of the few good reasons to call gc.Collect is as a last-ditch effort to free up resources that weren't properly disposed, WaitForPendingFinalizers would seem a necessary step. Not sure what the best practice would be to avoid calling gc.Collect excessively in such cases, though. BTW, I wonder if there's any technical reason that gc.Collect 'has' to promote generations? It would seem more useful to have generations stay put unless enough stuff has been allocated in one to justify advancing it.Capablanca
Note for beginners in C# (like me): GC force call doesn't guarantee, some concrete unused object be removed from memory. (one way to do this is using of "using statement" (msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx))Eipper
Why is it supposed to be important to call WaitForPendingFinalizers?Clitoris
Y
21
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.

Yenyenisei answered 23/11, 2010 at 15:4 Comment(0)
V
15

GC.Collect()

Vivienviviene answered 23/11, 2010 at 15:4 Comment(0)
D
13

GC.Collect();

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

Diamagnetic answered 23/11, 2010 at 15:4 Comment(2)
What do you mean by that? What could it unexpectedly clean?Perm
@Voldemort - It wouldn't unexpectedly clean anything. But it may not clean up everything that you expect it to.Diamagnetic
I
6

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()
Icebreaker answered 23/11, 2010 at 15:5 Comment(3)
I prefer @Karthik's answer, there can be situations where an app should legitimately call GC.Collect(). Very rarely though.Hearken
Say you had an array of weak references and wanted to check if any 'live' references existed. It would make sense to call GC.Collect() before checking. Just saying.Truditrudie
Downvoted because the opening statement is factually incorrect; Yes, I do want to force the garbage collector to run.Homegrown
G
6

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();
Genesa answered 29/12, 2020 at 11:16 Comment(0)
T
5

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.

Tacket answered 10/8, 2016 at 2:40 Comment(0)
B
0

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
}
Blah answered 21/10, 2021 at 6:41 Comment(0)
T
0

Invoking GC.Collect() method explicitly may not clear the memory in the heap for the objects you wanted to. It internally manages to keep memory available for the application to run and allocate memory for the objects by disposing objects which aren't used for a while. Do it only in case your application or code requires more memory while execution.

Triennial answered 7/2, 2023 at 3:22 Comment(1)
This is more a comment than an answer, and should be posted as such.Opinionative

© 2022 - 2024 — McMap. All rights reserved.