9

I heard that C# does not free memory right away even if you are done with it. Can I force C# to free memory?

I am using Visual Studio 2008 Express. Does that matter?

P.S. I am not having problems with C# and how it manages memory. I'm just curious.

Jason D
  • 2,303
  • 14
  • 24
jim
  • 143
  • 2
  • 2
  • 7
  • 21
    Stop it. Don't. Leave it alone. Don't you dare. No. Not yours. Go away, think about something else. –  Dec 05 '09 at 18:16
  • 3
    @Will. Touched on a sore spot did he? – Jason D Dec 05 '09 at 18:21
  • @Jim Unless you are an expert and know what you are doing I would not. Even as an expert I wouldn't do it. If you are finding yourself needing to call the GC I would bet there is another issue... i.e. a *memory leak*. – Chuck Conway Dec 05 '09 at 18:30
  • 2
    @Charles, if you have a long running service, or a CLR function in SQL-- one that's processing TONS of text --in a 24x7 server environment, you will have the need to do this... It shouldn't be done liberally as it's an expensive operation, however there is the occasional need. – Jason D Dec 05 '09 at 18:34
  • 1
    IIRC GC.Collect will take any objects that are *not* due to be collected and promote them to the next generation, where they are *less* likely to be collected next time. – Tim Robinson Dec 05 '09 at 18:34
  • Jason D. Why does it show that you edited my post? I don't see any changes... – jim Dec 05 '09 at 18:56
  • By due to be collected, do you mean ones with no references, or is there some other heuristic the garbage collector uses? – jim Dec 05 '09 at 19:01
  • 2
    @Jason D: I find your claim that you *will* need to do this rather bold. I've written long-running 24x7 services which haven't required this at all. Where and why do you find the need? – Jon Skeet Dec 05 '09 at 19:23
  • @Jason D - we write lots of long-running windows services and never have a need to touch the GC. – Joe Dec 05 '09 at 23:39
  • 1
    @Jon Skeet, As I said before it's a SQL CLR function. It's running under SQL 2005 and as i indicated before it gets to process TONS of text at once. I didn't write the thigs, a colleage did. He found that it would run out of SQL CLR memory unless GC.Collect was called periodically (i.e. not all the time... but more than never) He's a very thorough person. I trust his assessment. @Joe. Thanks for sharing. – Jason D Dec 06 '09 at 03:28
  • @jim - to answer your comment about Jason D's changes - he added the `.net` tag. – ChrisF Jan 04 '10 at 21:50
  • Possible duplicate of [How to force garbage collector to run?](http://stackoverflow.com/questions/4257372/how-to-force-garbage-collector-to-run) – Michael Freidgeim Jun 03 '16 at 01:13

4 Answers4

20

Jim,

You heard correctly. It cleans up memory periodically through a mechanism called a Garbage Collector. You can "force" garbage collection through a call like the one below.

GC.Collect();

I strongly recommend you read this MSDN article on garbage collection.

EDIT 1: "Force" was in quotes. To be more clear as another poster was, this really only suggests it. You can't really make it happen at a specific point in time. Hence the link to the article on garbage collection in .Net

EDIT 2: I realized everyone here only provided a direct answer to your main question. As for your secondary question. Using Visual Studio 2008 Express will still use the .net framework, which is what performs the garbage collection. So if you ever upgrade to the professional edition, you'll still have the same memory management capabilities/limitations.

Edit 3: This wikipedia aritcles on finalizers gives some good pointers of what is appropriate to do in a finalizer. Basically if you're creating an object that has access to critical resources, or if you're consuming such an object, implement IDispose and/or take advantage of the using statement. Using will automatically call the Dispose method, even when exceptions are thrown. That doesn't mean that you don't need to give the run finalizers hint...

Jason D
  • 2,303
  • 14
  • 24
9

You can't force C# to free memory, but you can request that the CLR deallocates unreferenced objects by calling

System.GC.Collect();

There is a method WaitForPendingFinalizers that will "suspend the current thread until the thread that is processing the queue of finalizers has emptied that queue." Though you shouldn't need to call it.

As the others have suggested head over to the MSDN for more information.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • GC.RunFinalizers? where it is? I can't find it in my VS 2010 C# 4.0 – Imran Rizvi Jun 12 '13 at 13:11
  • @ImranRizvi - apparently it was removed a long time ago - http://stackoverflow.com/a/12565583/59303. – ChrisF Jun 12 '13 at 13:14
  • [MSDN documentation](https://msdn.microsoft.com/en-us/library/xe0c2357%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) on this method states that it *Forces an immediate garbage collection of all generations* – Thomas C. G. de Vilhena Jul 28 '16 at 18:46
2

You can force the garbage collector to collect unreferenced object via the

GC.Collect()

Method. Documentation is here.

Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172
0

You can clean up your memory by given both methods:

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

Read both Reference GC.Collect() and GC.WaitForPendingFinalizers()

Anjan Kant
  • 4,090
  • 41
  • 39
  • 1
    And does this actually work? Anyone tried? Or is this an urban legend being passed around as truth? – ajeh Mar 22 '18 at 21:46