2

I'm aware that GC will clean objects on the heap when there's no longer any reference to them on the stack.

I wonder if there's a way to force GC to act before that. The scenario I have is something like this.

public void A(){ IList foo = bar(); //does work on foo's items foobar(); //more code before it goes out of scope } 

I wish I could free the memory used by the collection before calling foobar(). Is there a way to do that?

ps.: I know it's bad code, but it's a legacy code which I can do nothing about right now.

UPDATE: As pointed out by InBetween, "The GC is allowed to collect any unrechable object, but it's not a certainty it will do so". Unfortunately, I have a memory requirement from some users and the app must keep its memory usage within certain limits, otherwise I'd usually let GC do its work.

9
  • You can call GC.Collect(); manually, but there's no guarantuee it will work as intended. Commented Aug 29, 2017 at 14:48
  • 2
    I'm aware that GC will clean objects on the heap when there's no longer any reference to them on the stack. Hard to be aware of something that isn't true. Commented Aug 29, 2017 at 14:49
  • I seem to recall that this already happens: the GC won't wait until the end of the method before reclaiming memory (if no further references are encountered in the method) so it might very well be reclaimed already. Commented Aug 29, 2017 at 14:52
  • 2
    @MichaelCoxon no, that just sets the reference to null. The actual collection is still there. Commented Aug 29, 2017 at 14:54
  • 1
    @JeroenVannevel The GC is allowed to collect any unrechable object, but it's not a certainty it will do so. To make sure it does you should call GC.Collect but you shouldn't be doing that unless you have a very good reason. Let the GC do its job, it's much better at it that any of us. Commented Aug 29, 2017 at 14:56

2 Answers 2

3

I'm aware that GC will clean objects on the heap when there's no longer any reference to them on the stack.

That is not true:

var o = new object(); return new[] { o } 

Ok, where exactly is the reference to o on the stack after this method returns?

Think of it better this way: any object is eligible for collection if the GC can prove that it's not reachable any more. That is quite different from what you're claiming.

Additionally, if the GC can prove that no reference to a given object is ever read from again then the object can be collected even if there is a reachable reference (because it's never used so it's as good as unreachable).

Both these scenarios are performed by the GC for you when the GC decides it's a good time to do so; it is much better at it than you, so let it do its job and don't worry about it. There are very little scenarios where you have to interfere with how the GC works.

Sign up to request clarification or add additional context in comments.

1 Comment

I was indeed mistaken. Thanks for clearing it up. I'd normally not try to manage the memory myself, but there's a small set of clients running the app who demand it not use more than X memory, so I have to try to keep it within these bounds. Thanks again.
2

Garbage Collection in .NET is called in 3 situations :

  1. Allocation exceeds the first generation ( gen 0 ) or large object heap threshold,
  2. System is low on memory,
  3. By calling GC.Collect method

Judging by your "code" I can guess that it will be called as in first situation and in this case ( because you still have a reference to that object ) I would suggest you to wrap this in to some other code block. eg :

public void A () { DoSomethingWithTheList(); foobar(); //more code before it goes out of scope } private void DoSomethingWithTheList() { IList foo = bar(); //does work on foo's items } 

If that's not possible then just try to dereference your IList object by setting it to null and then invoke GC.Collect with the highest generation as a parameter which should do the trick.

public void A () { IList foo = bar(); //does work on foo's items foo = null; GC.Collect(2, GCCollectionMode.Forced); // force GC foobar(); //more code before it goes out of scope } 

this assumes that objects in the IList foo are not referenced elsewhere

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.