I’m using Unity version 3.5.0f5. When I allocate memory for a big array (of byte, double, whatever), it is never garbage collected. For example:
void Start () { double[] bigArray = new double[100000000]; Debug.Log((bigArray.Length * sizeof(double)) / (1024*1024) + " MB memory allocated"); //when leaving Start(), this local variable "bigArray" should be garbage collected //since it isn't referenced anywhere and is out of scope }
You’ll see the message “762 MB memory allocated” and if you check system memory (Ctrl-Shift-Esc in Windows), this memory is allocated but never freed. Even when you stop running this in the Unity Editor, the memory is still not freed.
How can I create a big array and then free it in my C# code?
---------- UPDATE -----------
I created a simple console app in Visual C# and replicated the same behavior. The problem seems to be that the .Net garbage collector doesn’t work well (at least with big arrays that go on the Large Object Heap). When I created additional big arrays in a loop, the second memory allocation doubled the size of my footprint to about 1.5 GB, but then subsequent allocations apparently re-used the already allocated memory. When I did a GC.Collect(), it did recover about half the memory allocated, which is bad news because I shouldn’t need to call GC.Collect() at all.
I wrote some sample code (see below) to allocate unmanaged (unsafe) arrays using the Marshal class (adding “using System.Runtime.InteropServices;” to my class file), and it worked perfectly, allocating 762 MB of memory and then freeing all of it. No leaks.
//must go to Project / Properties, and check "allow unsafe code" using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; class Program { private static long size = 50000000; private static IntPtr myMemory; static void allocUnmanagedArray() { double[] doubleArray = new double[100]; Array.Clear(doubleArray, 0, 100); myMemory = System.Runtime.InteropServices.Marshal.AllocHGlobal((int)size); for (int i=0; i < size-200; i += 100) Marshal.Copy(doubleArray, 0, myMemory+i, 100); Console.WriteLine("created unmanaged array: " + (size / (1024*1024)) + " MB"); } static void freeUnmanagedArray() { Marshal.FreeHGlobal(myMemory); } static void testAllocatingUnmanagedArrays() { for (int i = 0; i < 5; i++) { Console.WriteLine("Hit Return to allocate an unmanaged array: " + (i+1) + " of " + 5); Console.ReadLine(); allocUnmanagedArray(); Console.WriteLine("Hit Return to free an unmanaged array"); Console.ReadLine(); freeUnmanagedArray(); } } static void Main(string[] args) { testAllocatingUnmanagedArrays(); Console.WriteLine("Hit Return to Exit Console"); Console.ReadLine(); } }