iPhone: How do I ensure I'm not allocating memory in Update?

The Unite session on optimizing for iPhone recommended not allocating memory in Update. How do I ensure I'm not allocating memory? Does that mean I shouldn't declare any variables in Update?

This question recently came up on the #unity3d IRC channel (jasontuttle asked the question, and mike_mac gave the answer which I have paraphrased/expanded below).

  • Don't worry about declaring primitive value type variables (such as ints).
  • Don't worry about declaring reference type variables that refer to existing GameObjects or Components.
  • Do avoid the frequent creation of new GameObjects, Components, and other reference types.
  • Do avoid making frequent calls to expensive functions like FindGameObjectsWithTag or GetComponent. Call them once (e.g. in Awake) and cache the results.
  • Also be aware that accessing game object properties (such as gameObject.transform) actually causes a call to GetComponent behind the scenes. See this question for more information.
  • In addition to Update, this advice also applies to FixedUpdate, OnGUI, and any other functions which are called frequently during game execution.

See also:

It sounds like the advice was that you not allocate memory repeatedly - if you're allocating memory every frame in Update or in similar callbacks, that's not desirable on any platform, but if it's just once in a while, e.g. if you a few objects that you can create on demand, that might not be so bad.

Nonetheless, to avoid memory allocation you want to watch out for code that creates objects (including arrays) - watch out for "new" and "Instantiate", especially for objects that you're just creating and throwing away (via the garbage collector) or worse, hanging around because of some remaining references. Depending on your application, you may want to preallocate/precreate objects or set up a pool to reuse them, but the advice about premature optimization applies.

I think there's an open question about whether using iterators allocates memory, or at least to the degree you shouldn't use them (like if you're iterating among the children of a transform).

The final arbiter is the profiler - if you have that activated per the Unity iPhone manual, the XCode console will show you if memory usage increases in any alarming way.

In addition to the above rules of thumb:

Duplicate the project - and import a copy into Unity 2.6. Turn on Deep Profile.

Use the Unity 2.6 profiler to determine where you are allocating memory and why. Eliminate the allocations.

Beats the heck out of guessing.

Correct me if I'm wrong, but you want to place as many allocations as possible in the Start() method. Start is essentially initializing the script.

it seems like you have been facing some hardware issues, make sure it is not connected with the unlocking iPhone issue.