• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by jeffssmith1 · Mar 09, 2012 at 08:35 PM · arraysmemorygarbage collector

Big arrays are never garbage collected. Why?

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();

} }

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Paulius-Liekis · Jan 21, 2016 at 02:13 PM 0
Share

Have you figured out what's happening? I'm seeing the same problem - large blocks are sometimes not collected at all until you run out of memory. Is there an explanation for this behaviour? Is there a way to avoid it?

I'm reseting my references to null; I'm calling CG.Collect manually.

avatar image Pulas · Jul 02, 2016 at 03:06 PM 0
Share

I have to create some AssetBundles from memory, which are large byte array. When I create those too many times, it will throw out of memory exception. I tried setting byte to null and GC.Collect(), but it did not work, the memory still not collected. How to solve this kind of problem? $$anonymous$$arshal.AllocHGlobal only creates unmanaged memory, but the AssetBundle.CreateFrom$$anonymous$$emory can only take byte[] as params.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by DaveA · Mar 09, 2012 at 09:21 PM

You may find these helpful: http://msdn.microsoft.com/en-us/library/ms973837.aspx

http://www.devx.com/dotnet/Article/33167/1954

http://unity3d.com/support/documentation/Manual/Understanding%20Automatic%20Memory%20Management.html

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jeffssmith1 · Mar 09, 2012 at 10:48 PM 0
Share

Thanks for the links. I think there are two options for large arrays in .Net/Unity: 1) $$anonymous$$aintain an some sort of array object pool 2) allocate unmanaged (array) memory and free it myself

I'm leaning towards trying option (1) since it would be nice if my app runs in the web player.

avatar image jeffssmith1 · Mar 10, 2012 at 12:03 AM 0
Share

Changed my $$anonymous$$d and used (1). The object pool approach worked for me, but I still find it disconcerting that the .Net garbage collector seems to fail for large arrays.

avatar image Julien-Lynge · Mar 10, 2012 at 05:28 PM 1
Share

@DaveA

Your first two articles are absolutely correct for .NET, but the current version of Unity is running an older version of $$anonymous$$ono (2.6), which uses the Boehm garbage collector - this collector is not generational and does not match how .NET's garbage collector works. For instance, the release notes for 2.8 (http://www.mono-project.com/Release_Notes_$$anonymous$$ono_2.8) says the following about 2.6:

"$$anonymous$$ono has historically used Hans Boehm's conservative Garbage Collector, a fantastic garbage collector. As $$anonymous$$ono evolved, we wanted to bring some extra features like generational garbage collection that were not possible with Boehm. "

avatar image jeffssmith1 · Mar 11, 2012 at 02:50 PM 1
Share

I would dispute their characterization of Boehm's garbage collector being "fantastic" since it never collects the memory from large arrays (allocated on the Large Object Heap), regardless of whether the array falls out of scope or is set to null. :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Device specific texture resolutions? 1 Answer

Assetbundle loaded asset cannot be cleaned in Android 1 Answer

Why a texture always consume twice RAM when running? 1 Answer

Shader memory consumption. 2 Answers

Asset Bundle Limitations 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges