I'm really need help! I can't understand how to work with prefabs and unloading.
I have the next situation.
I run my application on IPad from Xcode. Unity version 4.3.1 Pro. Watch memory using with: Xcode Debug Navigator Xcode Instruments Unity Profiler
I do next steps:
0) Unity starts from Empty scene.
Used memory XCODE Debug Navigator: 11 mb Instruments: 26.4 mb Unity Profiler: used total 13.2 reserved total 13.7
1) Load prefab from Resources folder
prefab = Resources.Load("Room1");
Used memory XCODE Debug Navigator: 30.8 mb Instruments: 49.54 mb Unity Profiler: used total 19.8 reserved total 20.4
2) Instantiate prefab
go = (GameObject)Instantiate(prefab);
go.name = "Room1";
XCODE Debug Navigator: 31.2 mb Instruments: 50 mb Unity Profiler: used total 20 reserved total 20.7
3) Destroy all objects on scene - memory not changed
Transform[] tr = FindObjectsOfType<Transform>();
for (int i = 0; i < tr.Length; i++)
{
GameObject goo = tr.gameObject;
if (goo.name != "Main Camera")
{
Destroy(goo);
goo = null;
}
}
XCODE Debug Navigator: 31.1 mb Instruments: 49.93 mb Unity Profiler: used total 19.8 reserved total 20.4
4) Call Resources.UnloadUnusedAssets();
- memory not changed
5) Call System.GC.Collect();
- memory not changed
6) Call UnloadAsset of prefab Resources.UnloadAsset(prefab);
- memory not changed
7) Call Resources.UnloadUnusedAssets();
- memory partially cleaned
XCODE Debug Navigator: 21.9 mb Instruments: 40.79 mb Unity Profiler: used total 13.2 reserved total 13.9
In profiler i see, that deleted all texures, that used in prefab
8) System.GC.Collect();
- memory not changed
9) Load empty scene - memory not changed
Here is another interesting moment:
When application goes to background and i start another application, size of used RAM greatly decreases, and when i call unity app - memory goes to first size with empty scene.
I have next questions:
1) Why memory not cleaned fully after delete prefab and call UnloadUnusedAssets - we can see it in Instruments and Xcode - but in Profiler we see, that memory practically fully free?
2) It's real to clean memory to initial size?
3) Do i all steps right or i do something wrong?
You can download test project here: http://gfile.ru/aa5on
Big thanks for your replies.
It is good that you are aware of RAM usage. But, the question is: have you encountered any problems with memory usage so far? If not, then what you do is premature.
Here are some thoughts for you to consider:
Once you allocate a certain amount of memory, it is reserved for mono and not available for the OS. Even when you release it, it will become available internally for Mono only and not for the OS. The heap memory value in the Profiler will only increase, never decrease.
Object.Destroy
doesn't destroy object instantly:
Actual object destruction is always delayed until after the current Update loop, but will always be done before rendering.
Resources.UnloadUnusedAssets
is async. It doesn't unload everything instantly.Resources.UnloadAsset(Object assetToUnload)
will unload resources referenced by assetToUnload
. I can't call myself an expert in memory management (of both Unity and Mono). But here is how I understand what's going on:
1) Load prefab from Resources folder
Prefab was loaded with all the resources referenced by it. Memory usage increased. Everything is clear now.
2) Instantiate prefab
Memory usage increased a bit to hold prefab clone.
3) Destroy all objects on scene - memory not changed
Here come interesting things :) Actually, memory usage has changed according to Unity's profiler: it is the same as it was before instantiation of prefab. So, it looks like Unity has released something that was directly related to the prefab instance. But, as it is said, mono will not return memory to OS (and it's not even time for it to do so even if it did).
4) Call Resources.UnloadUnusedAssets(); - memory not changed
Resources.UnloadUnusedAssets
fails to unload anything here, because there are still no unused assets: though objects were marked for destruction, actual garbage collection hasn't took place.
5) Call System.GC.Collect(); - memory not changed.
It's because it's memory managed by mono.
6) Call UnloadAsset of prefab Resources.UnloadAsset(prefab);
I believe that memory usage has dropped a bit here (100K-200K or so) but you haven't noticed it. But, as I have mentioned above, UnloadAsset
will not unload resources that referenced by object that you pass as a parameter to UnloadAsset
.
7) Call Resources.UnloadUnusedAssets(); - memory partially cleaned
On step 5 you have invoked GC.Collect(), collection has occurred and now some of the Unity assets have no references to them. Thus they can be freed finally. That's why memory has been freed.
8) System.GC.Collect(); - memory not changed
Explained above
9) Load empty scene - memory not changed
Everything that could be freed have been freed already. Thus no change in memory usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With