6

I was just writing a function (in C# in this case) that stored huge amounts of data in a local variable early on in the code, let's say at 5% of the functions code.
After that point, the data in this memeory are no longer used,
also the following 95% of code have a variable runtime, as part of it depends on external ressources.
My Idea was (inspired by C) to 'actively free' that block of memory.
In an evironment with a GC this is mostly just plain impossible.

My idea:
memeoryMonster = null;
Why this?
The GC would never collect that object while the execution is still inside the function, because the variable is still in scope and thus connected to the object graph.
This line would remove the reference to the object and thereby disconnect it from the object graph.
I'm not actively calling the GC, but we know it runs if either the memory runs low, which might happen in the second part of the function or at any time
or all other threads are idle, which might very well happen when the code waits for the external ressources i.e..
This way I want the GC to be able to collect that memory, if need be.

Also I realize that it's probably better to split that function into several parts, which I have done by now, or at least pack the memory-heavy part into a pair of {} to make it get its own scope, so the question is of theoretical nature.

My question:
Does this work like I think it does?
Does setting local variables to NULL enable the GC to collect the memory they occupied?

  • 2
    I don't know much C#, but why not just isolate any processing of the monster data in some other scope (most likely a function call)? If you can set it to NULL, that must mean you don't need it after that point; any intermediate variables could be returned from a function. That should sidestep the whole problem. – detly Oct 28 '14 at 7:21
  • If you read the second-to-last paragraph you'll find that I already did that, but thanks for confirming my idea that that is a neater, less cumbersome approach. – Mark Oct 28 '14 at 7:23
  • 1
    Ah, I think I read it before the edit where you explicitly mentioned {}, so it didn't click. Yes, I think it'd be neater all round :) – detly Oct 28 '14 at 7:38
11

I wouldn't say that, but your explanation in the middle of the question text is basically sound.

First, the object may be reachable through another reference. This should be obvious, but it's a common beginner mistake to "make the object null" when there are three other references in the same function.

Second, in some environments (.NET is one example off the top of my head), the optimizer may very well drop the reference before the end of its scope if it's never used through the latter 95% of the code. If so, it's redundant.

Finally, free is a bad analogy. I understand why you chose it, and this is more of a nitpick, and you phrase it better in other parts of your answer, but thinking of it as an analogue to free is not helpful IMHO. It's not prompt, it only possibly enables deallocation instead of forcing it (see the above point about other references), and a misplaced = null is not nearly as dangerous as a misplaced free().

After all these caveats though, yes, if a local variable is the only reachable reference to an object (graph), then setting it to null will enable the GC to collect those objects earlier if the GC runs between the null assignment and the end of the scope of the variable. How common this situation is is a whole other question, among other things it depends on how many objects are created by the rest of the code. In my experience, this is an extremely rare situation, hence my skepticism if this course of action is necessary.

  • 1
    Thanks for the detailed answer. I guess this won't be the next big thing in programming then, I guess. ;-) That I don't set the OBJECT to null, but only one (of possibly many) reference to it, I knew. About the optimizer however, I completely forgot. – Mark Oct 28 '14 at 7:20
  • +1. There's an Ocaml/F# example of objects being collected before their scope ends on Jon Harrop's blog. It's a (non-tail) recursive function with an array parameter that immediately copies the array and then calls itself with the copy. The code doesn't run out of memory regardless of the number of iterations because the array parameter isn't used after it's copied, so its memory can be reclaimed. – Doval Oct 28 '14 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.