Need some clariforcation on memory allocation and memory leaks

I originally posted this up as a question but I think it’s better suited here to be honest…

Apart from the whole of yesterday, I’ve never looked into memory leaks before. I knew roughly of it but had read about c# and garbage collection etc so thought it would never be a problem. However, I’m working on a custom editor window and part of it involves dynamically drawing a texture, this texture changes size (i have a zoom feature) and this is where the “problem” started. At the moment, I haven’t restricted the amount you can zoom, and I’m creating a new array the size of the texture every time the texture needs to redraw (only when zooming, so not every frame). I am also creating a new texture each time. Now I know both of these are bad practices and I know how to change them to make them efficient. However, I have kept them both in for my own testing purposes to help me try and understand how memory works.

So i noticed a problem when looking at task manager and the memory usage. When I zoomed (in or out) the memory gradually increased and never decreased. However, the further you zoom in, the memory increases by more. It doesnt take much to get the memory usage to 2 gig and then out of memory exceptions start getting thrown. Eventually Unity will freeze. So at first I thought it was the creating of a new texture each time rather than the array that was causing the problem. But after looking in the profiler, it turns out that 99% of the problem is the arrays. The textures memory allocation is actually handled extremely well from what I can gather. (it would never go above ~150Mb of used space for textures).

So I spent all of yesterday researching about Unity’s (monos) garbage collection etc. I read the 3 blog posts on gamasutra which were really good, but seemed like they might be a bit outdated now since 4.5 has come out. They also didn’t explain all the little details that I’m personally really interested in. The blog posts mention that mono for unity uses the Boehm garbage collector and not the Generational one. But this was on Unity 4.3 so is this still the case on 4.5? Because I ran some foreach tests (which are apparently bad in Unity) and yet I didn’t see any memory problems. I did many tests using different types (color, vector3, int, string, myownclass) and used a ridiculous (10,000,000) sized array. Infact, I noticed that I was only getting memory problems from my editor scripts. For example, my editor script starts creating arrays around the 9,000,000 mark if you zoom far enough and this is when the memory usage starts to get around 1.6 gig. But if I create a 9,000,000 sized array in a monobehavior script every frame, when I click play and monitor the profiler and task manager, theres no increase in memory at all, it stays roughly around the same amount. I really can’t get my head around it all.

Theres more… In the profiler under memory, you have your “used” memory and your “reserved” memory. I’ve read the info in the manual about it and all I learnt was that reserved memory for mono only goes up, never down. On top of that, the numbers in the profiler never match up to the number in task manager. I’ve read this is because the profiler doesnt account for some stuff that task manager does. I understand that, but what I don’t understand is how the numbers can be so far off from each other. For example I’ve had readings similar to these:

Used total: 200mb
Reserved total: 1.6gb
Task manager: 600mb

Used Total: 150mb
Reserved total: 400mb
Task Manager: 2GB

I’d understand if the reserved total was either always more or always less than the task manager amount. But it’s not, it varies so dramatically. Entering and exiting play mode and recompiling sometimes cause the memory usage to change in either task manager or the profiler, but again this is not stable either.

If anyone would be kind enough to explain to me about memory allocation in Unity (I honestly understand if no one can/wants to!!) or point me in the direction of some good reads (but I swear I’ve read nearly every forum post and article on google) I would really appreciate it!!

Do you explicitly destroy your Texture instance once you don’t use them anymore?

DestroyImmediate(MyTexture, false);

At the moment, no. But also at the moment I have commented out anything to do with creating or setting the pixels of the texture but have left all other logic in, which includes the arrays being declared etc. I should’ve also mentioned how I’m going to change my code. I’m going to set a zoom limit in pixels, then create a member array the size of the max width x max height and just use whatever portion of the array I need to. So this will stop the huge arrays being created whenever a zoom occurs and will just have the one array. And with the texture, I’ll also just created one and change the size of it when needed and then re set the pixels. Should have done these in the first place really but kind of glad I didn’t because it’s made me aware of memory allocation and garbage collection.

Here is an example of what task manager says vs what unity says. Why is the reserved memory more than what windows says it has?!

Unity 4.6 uses Mono 2.6 and Unity 5 also uses Mono 2.6, which has the terrible Boehms garbage collector. This is a major problem for those of us who need to allocate large arrays at various points in our Unity application. Basically, large arrays are never garbage collected and eventually your application may run out of memory and crash.