1
\$\begingroup\$

I have two array lists. that I want to swap each frame. My question is, does the variable 'temp' need to be a member variable to avoid triggering GC, assuming this method is called on dozens of objects each frame? I'm not creating a new object, just a new reference to an object.

public void LateUpdate(){
    ArrayList<int> temp = previousFrameCollisions;
    previousFrameCollisions = currentFrameCollisions;
    currentFrameCollisions = temp;
    currentFrameCollisions.clear();
}

I've been told there's no reason to make a primitive into a member variable just to avoid GC, so my best guess is that this also applies to object references.

\$\endgroup\$
2
  • \$\begingroup\$ Note that there is no correct answer to this in general (which is how your question is phrased -- languages with garbage collection features may operate differently from eachother). C# itself doesn't strictly define the behavior of its GC, although individual platforms (.NET and mono, for example) do and the question can be answered on that basis since you're using C#. \$\endgroup\$
    – user1430
    Oct 26, 2012 at 17:02
  • \$\begingroup\$ Good point. I guess I thought this situation would be the same for all, but I have no good reason to make that assumption. I modified the question. \$\endgroup\$
    – TenFour04
    Oct 27, 2012 at 3:14

3 Answers 3

6
\$\begingroup\$

The GC is triggered by allocating new objects. In the simpler sense, it's only triggered if you use the 'new' keyword (or call a function or language feature that uses it internally, e.g. many GetEnumerator() implementations invoked by the 'foreach' keyword).

Assigning to variables -- member or otherwise -- will not cause the GC to trigger.

Also note that C# has excellent debugging and profiler tools, and you can always just test your code to see if it's triggering the GC or not.

\$\endgroup\$
1
\$\begingroup\$

Swap them, see if it causes any problems for you, and if not, then don't worry about it.

In other words - don't try to pre-emptively guess the runtime's behaviour. You risk causing even bigger problems for yourself that way. The time to deal with GC issues is when you know for certain that you have GC issues, not before - managed languages these days are extremely clever and GC overhead can be blown out of proportion in popular mythology; the common case is that the memory is just going to be returned to a "free" pool (a simple pointer swap) and very quickly reused (another pointer swap) so this is not really going to be that big a deal - particularly for simpler data types (like your ArrayList of ints).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ That's a good point. I guess I was looking for a rule of thumb for avoiding problems down the line. I don't need to wait to see that if I instantiate and let pass out of scope dozens of objects per frame, it's going to cause stuttering. So I was wondering if there was another basic guideline like that to follow when it comes to reference variables. \$\endgroup\$
    – TenFour04
    Oct 27, 2012 at 3:18
0
\$\begingroup\$

GC uses reference counting and will only trigger cleanup of an allocated block if there are zero references remaining (at the time when the GC sweep comes around). So by using temp for the swap, you won't trigger GC.

In other words, at no point are there zero refs to either of the two arrays you are allocating, in your code above. So don't worry.

\$\endgroup\$
5
  • \$\begingroup\$ Both mono and .NET use mark-and-sweep based collectors by default; while it's true that that does mean an unreferenced thing will be collectable, neither implementation actually uses reference counting. \$\endgroup\$
    – user1430
    Oct 26, 2012 at 17:04
  • \$\begingroup\$ @JoshPetrie Thanks, I knew it was something along those lines. I work with Mono .NET and Java so I don't always claim to know the exact specifics of each. \$\endgroup\$
    – Engineer
    Oct 26, 2012 at 17:05
  • \$\begingroup\$ -1: It's also incorrect that the GC is triggered when an object goes out of scope; the GC is triggered during allocation. Even I'd one If the two objects was thrown away, the GC would not trigger (unless a replacement buffer was created). \$\endgroup\$ Oct 26, 2012 at 17:10
  • 1
    \$\begingroup\$ I don't see a reference to scope here, before your comment? \$\endgroup\$
    – user1430
    Oct 27, 2012 at 3:18
  • \$\begingroup\$ I meant scope as in referenced (eg including member variables). Should've been clearer and just said referenced, sorry. \$\endgroup\$ Oct 27, 2012 at 18:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .