<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[Andrew Fray]]></provider_name><provider_url><![CDATA[https://andrewfray.wordpress.com]]></provider_url><author_name><![CDATA[afray]]></author_name><author_url><![CDATA[https://andrewfray.wordpress.com/author/afray/]]></author_url><title><![CDATA[Reducing Memory Usage in Unity, C# and&nbsp;.NET/Mono]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>Unity on iOS uses an early version of Mono&#8217;s heap manager. This manager doesn&#8217;t do packing, so if you fragment your heap, it&#8217;ll just grab a new one for you. I am under the impression the Unity boffins are working on a new heap manager to get around this problem, but for now a game with no memory leaks can end up consuming ever-increasing amounts of memory. C# is a fun language that allows you to quickly write powerful code without sacrificing readability. However the downside to this is that writing natural C# code produces a lot of garbage collection. The only way around this is to eliminate or reduce your heap allocations. I&#8217;ve compiled a handy list ways to do this without reducing functionality. The end effect is that your C# code looks much more like C++, and so you lose some of that C# power, but such is life. As an added bonus, heap allocs are inherently more CPU-intensive than stack allocs, so you&#8217;ll probably save some frame time as well. To target your efforts, the Unity profiler can help you functions that make a lot of allocations. It&#8217;s not a lot of info, but it&#8217;s there. Open the profiler and run the game,  select the CPU profiler, and tap the GC Alloc column to sort by the worst offenders. Apply these guidelines to those functions first.</p>
<ul>
<li><strong><em>Avoid using foreach()</em></strong>. It calls GetEnumerator() on your list type, which will allocate an enumerator on the heap just to throw it away. You&#8217;ll have to use the more verbose C++-style for(;;) syntax. <b>EDIT:</b> <em>Unless</em> you&#8217;re foreach-ing over an array. That causes no allocations. I guess that&#8217;s a special case that becomes syntactic sugar for a for(&#8230;){}? Thanks to <a href="https://www.google.co.uk/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;ved=0CC8QFjAA&amp;url=http%3A%2F%2Fwww.cs.northwestern.edu%2F~ian%2F&amp;ei=8BMTUoauHsP30gWoi4HoCw&amp;usg=AFQjCNFdGK9556Mt3hddjUq2opYcVq5L8A&amp;bvm=bv.50952593,d.d2k">Ian Horswill</a> for pointing that out.</li>
</ul>
<ul>
<li><strong><em>Avoid strings</em></strong>. Strings are immutable in .NET and allocated on the heap. You can&#8217;t manipulate them in-place like C. For UI, use <a href="http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx">StringBuilders</a> to build up strings in a memory-efficient manner, delaying the conversion to string until as late as possible. You can use them as keys because literals should point to the same instance in memory, but don&#8217;t manipulate them too much.</li>
</ul>
<ul>
<li><strong><em>Use structs</em></strong>. Struct types in mono are allocated on the stack, so if you have a utility class that won&#8217;t leave scope, make it a struct. Remember structs are passed by value, so you will have to prefix a parameter with ref to avoid any copy costs.</li>
</ul>
<ul>
<li><strong><em>Replace scope-bound fixed-size arrays with structs</em></strong>. If you have a fixed-size array that doesn&#8217;t leave scope, consider either replacing it with a member array that you can reuse, or create a struct with fields that mirror it. I replaced a Vector3[4] that was allocated every time you called our spline class with a ControlList struct that had four fields. I then added an this[] property for index-based access. This saved a ton of allocations because it was such a high-frequency function.</li>
</ul>
<ul>
<li><em><strong>Favour populating lists passed as ref parameters over returning new</strong></em><strong> <em>lists</em>.</strong> This sounds like you&#8217;re not saving anything &#8211; you still need to heap-alloc the list you pass in, right? &#8211; but it allows us to, where necessary, make the next particularly ugly optimisation:</li>
</ul>
<ul>
<li><em><strong>Consider storing the scope-local storage of a high-frequency function as a member variable.</strong></em><strong> </strong>If your function needs a big list every time it&#8217;s called, make that list a member variable so the storage persists between frames. Calling .Clear() on a C# list won&#8217;t delete the buffer space so you have no/less allocs to do next frame. It&#8217;s ugly and makes the code less readable so needs a good comment, but can make a big difference on heavy lifters.</li>
</ul>
<ul>
<li><strong><em>Avoid IEnumerable extension methods</em></strong>. It goes without saying that most Linq IEnumerable extension methods, as handy as they are, will create new allocations. However I was surprised that .Any(), called on an IList&lt;&gt;, which I expected to just be a virtual function to Count &gt; 0, triggered an allocation. It&#8217;s the same for other funcs that should be trivial on an IList, like First() and Last(). If anyone can illuminate me on why this is I&#8217;d appreciate it. Because of this, and the foreach() restriction, I&#8217;d go as far as to say avoid the IEnumerable&lt;&gt; abstraction in your interfaces, and use IList&lt;&gt; instead.</li>
</ul>
<ul>
<li><b><i>Minimise use of function</i> <em>pointers</em>.</b> Putting a class method in a delegate or a Func&lt;&gt; causes it to be boxed, which triggers an allocation. I can&#8217;t find any way to store a link to a method without boxing. I&#8217;ve left most of my function pointers in there because they&#8217;re a massive boon to decoupling, and I&#8217;ll just have to live with the allocs, but I&#8217;ve removed some.</li>
</ul>
<ul>
<li><em><strong>Beware cloned</strong></em><strong><em> materials</em>.</strong> If you get the material property of any renderer, the material will be cloned even if you don&#8217;t set anything on it. This material isn&#8217;t GC&#8217;d, and is only cleared up when you either change levels or call Resources.UnloadUnusedAssets(). Use myRenderer.sharedMaterial if you know you don&#8217;t want to adjust the material.</li>
</ul>
<ul>
<li><strong><em>Don&#8217;t use raw structs as keys in</em> <em>dictionaries unless..</em>.</strong> If you use a Dictionary&lt;K,V&gt; type, and your key value is a struct, fetching a value from the dictionary using TryGetValue() or the index accessor can, somehow, cause an allocation. To avoid this, implement IEquatable&lt;K&gt; for your struct. I guess the dictionary is creating some default equality comparer every time. Thanks to <a title="Ryan Williams on Twitter" href="https://twitter.com/quxmore">Ryan Williams</a> for finding this one.</li>
</ul>
<ul>
<li><em>2014/5/8</em> <em><strong>Don&#8217;t overuse Enum.GetValues() or myEnumValue.ToString()</strong>. </em>Enum.GetValues(typeof(MyEnum)) allocates an array with every call. Enum.GetNames() does something similar. If you&#8217;re like me, you&#8217;re probably using these heavily, along with .ToString() on enum variables, to do UI, as well as is other places. You can cache both these arrays easily, allowing you to do a for loop over enum values as well as cachedEnumNames[(int)myEnumValue]. This doesn&#8217;t work if your enum values are manually set, eg flags.</li>
</ul>
<p>Feel free to add more in the comments.</p>
<p><em>Shamless plug</em>: Easily add human-like and emergent decision making to your Unity3d game with <a href="http://www.tenpn.com/decisionflex.html">DecisionFlex</a></p>
]]></html></oembed>