The resources recycling is not complete

I’m working on a ftg game for iphone. I have 8 characters. Before the fight start, I load the 2 characters’ prefab in this round and instantiate them. But I found that the prefab object also cost skinning time during the game and I can’t find some solution to unload the prefab. Since after I destroied the prefab object, I cann’t load the resource any more. ( I’m using iphone 1.7 now, I’m not sure if this is fixed in the latest version. )

I found another to solve this is use AssetBundle that can unload the prefab and also can reload. But it cost more memory that Resources.Load, so I have to find some other way.

Finally, I create lots of scens that each one with 2 characters in it. After each battle, I load another scene.

But it disappoint me again. Each time I change the scene, the resource seems not recycling complete. So after I changed character several times, the memory is keeping growing.

Does some one know how to get back my memory?:-|:-|:-|

How are you ‘unloading’ your prefab?

Just like this,

var prefab : GameObject = Resources.Load( “a” );
var obj : GameObject = Instantiate( prefab );
Destroy( prefab );
prefab = null;

After this, I can’t load the resource except I restart the app.

This is not good because the “prefab” variable is a reference to the actual resource. “Destroy (prefab)” is an attempt to destroy the resource, which isn’t permitted; if you try that in the editor you’ll get an error message. Take out “Destroy” and leave “prefab = null”. Or better yet just do

var obj : GameObject = Instantiate( Resources.Load( "a" ) );

–Eric

I had tried that. But it still have problem. I had tested. If there is one character in the scene, the skining time is about 6ms. While after I instantiated the 2 characters, the skining time is about 26ms. The loaded resources also cost skining time here.

I had find some other way to solve this.

But the prolem is, when I play with different characters, the memory keeps growing until every character have been loaded during the game. It seems the memory if not be freed even I changed scene during the game.

If I can free those memory?

above code that eric quoted actually is meant to have Destroy(obj) in to get rid of it.
The same holds for any asset you load and mark as dontdestroyonload, if you ever want to get rid of it again

as for memory climbing: thats normal for GC driven environments. They raise till they reach a rather high fill and then start to clean up to prevent unrequired runs (the more memory a managed environment has in its hands the more performant it will become normally)

I’ve been trying to get familiar with Resources.Load lately and I can’t seem to remove a gameobject from memory that has been loaded from the resources folder. I’ve tried a few ways including Eric’s suggestion, but it does not actually get it out of memory.

What is interesting though is that I was able to remove a Texture from memory that was loaded via Resources.Load.

For both assets (the gameobject and texture) I was using Application.GarbageCollectUnusedAssets() to try and free the assets from memory. Since I am using Unity iPhone Pro 1.7, I cannot use the updated API for Resources which includes a remove method.

Reloading the scene clears the memory, but even then some memory gets left behind, according to when I test it using xCode Allocations.

Is there any other way that I can get a gameobject out of memory that was loaded using Resources.Load (without upgrading to Unity 3 Pro + iPhone Pro)?

Destroy and System.GC.Collect will get it out.
But ensure to also manually remove first all stuff you linked on the game object and that was loaded from resources, especially textures and audio.

also I don’t see why you would need pro of U3 unless you want asset bundles and those exist on Unity iPhone 1.x pro too

Ahh, manually remove all stuff from gameobject. Yeah my gameobject that I was testing with had a texture on it.

To recap so I understand: Since I am loading a prefab (essentially a gameobject) from Resources, I should manually remove ALL components from it, THEN call destroy, followed by a GC call.

I’ll try this out and run xCode Allocations tools to see if this works. Will post back here if it does.

And thanks for your assistance.

no, if the object as a prefab you loaded as a single thing you don’t need to manually kill anything.
Thats only required if you resource loaded stuff on it (or WWW loaded - for WWW especially check the texture handling if you load textures from there cause thats a common source for leaks), but if its a single prefab you can also kick it as a “single thing” again with destroy

the allocation tool is commonly only of minor use btw, cause it measures the application usage, that has nothing to do with the GC cause a GC environment will not nullify the pool it will keep a given pool thats relative in size to its previous full size, to grow again. And thats required cause memory allocation / deallocation against the OS is one of the slowest operations (see string performance on iOS for the more or less best known example of how impacting it is)

Thanks for the heads up on the Allocations tool. The tool is misleading because when I use it and perform something like Application.GCUnusedAssets() the memory does in fact go down after having loaded something like a simple texture.

So the major rule of thumb is anything that holds a reference to something loaded from Resources must be “killed” to ensure proper removal from memory. Then when the GC is ran (either manually or automatically), it will remove unused assets from memory.

Out of curiosity, how were you able to confirm this?

Thanks.