- Home /
Out of memory loading between levels
Howdy Unity gurus!!!
I get out of memory errors now and then just before loading scene "y" from secene "x". Scene"x" is moderate size, not tiny. Scene "y" only has two objects. One with a 1024 texture.
I'm trying the following:
Resources.UnloadUnusedAssets()
just before loading scene"y" but I'm not using any resource bundles. Would this have any effect? I'm assuming it would dump some memory.
Thx for any tips in advance on this issue.
Have you tracked the memory usage on Unity profiler or on the Windows taskmanager?
Thx for your comment! On closer inspection, scene"y" has several object. about 15 simple planes, (billboards) and two guitext. Two boned skinned meshes. I looked at the profiler. Below is what is reported for memory. Does it look like enough to crash 4th gen iOS devices? I get occassional crashes that are stopped by cold start of device, but it's not a valid fix I$$anonymous$$O.... Thx for any tips! scene"x" memory textures: 964 / 18 mb meshes 92 / 4.4mb total object count 14683
scene"y" textures: 959 / 10.3 mb meshes 41 / 285 kb total object count 2797
I'm sorry but I don't have much experience with iOS devices, so I will just throw some generic questions that came to my $$anonymous$$d:
Does it crash if start your game loading scene "y" before "x"? Do you use LoadLevelAdditive or LoadLevelAsync? Do you have many static objects (like static var obj : GameObject) or objects using DontDestroyOnLoad?
Answer by kromenak · Jan 25, 2012 at 09:39 PM
You can profile your memory usage using Instruments through XCode. Simply select Product > Profile from the menu bar, which will compile your app, put it on the device, and automatically open up Instruments (using XCode4, might be the same in XCode3). If you then select "Activity Monitor," you'll get a lot of data on the amount of memory you are using. Depending on your testing device, the acceptable amount of RAM varies.
iPhone3 (128MB total RAM): less than 40MB
iPad1 or iPhone3GS (256MB total RAM): less than 80MB
iPhone4, iPhone4S, iPad2 (512MB total RAM): less than 160MB
Another thing you might want to do is watch your XCode log and see if you are receiving memory warnings. Memory warnings are a pretty good indicator that you are using too much memory and the OS might shut you down.
Then, I've found the following code pretty useful to see everything that is loaded in memory at a given time. It will slow down your build a little bit because it uses UnityGUI, so use it for debugging only, not in production builds:
public class DetectLeaks : MonoBehaviour
{
private static DetectLeaks instance;
void Awake()
{
if(instance == null)
{
instance = this;
}
else
{
Destroy(this);
}
}
void Start()
{
DontDestroyOnLoad(gameObject);
}
void OnGUI()
{
if(GUILayout.Button("Unload Unused Assets"))
{
Resources.UnloadUnusedAssets();
}
if(GUILayout.Button("Mono Garbage Collect"))
{
System.GC.Collect();
}
if(GUILayout.Button("List Loaded Textures"))
{
ListLoadedTextures();
}
if(GUILayout.Button("List Loaded Sounds"))
{
ListLoadedAudio();
}
if(GUILayout.Button("List Loaded GameObjects"))
{
ListLoadedGameObjects();
}
}
private void ListLoadedTextures()
{
Object[] textures = Resources.FindObjectsOfTypeAll(typeof(Texture));
string list = string.Empty;
for(int i = 0; i < textures.Length; i++)
{
if(textures[i].name == string.Empty)
{
continue;
}
list += (i.ToString() + ". " + textures[i].name + "\n");
if(i == 500)
{
Debug.Log(list);
list = string.Empty;
}
}
Debug.Log(list);
}
private void ListLoadedAudio()
{
Object[] sounds = Resources.FindObjectsOfTypeAll(typeof(AudioClip));
string list = string.Empty;
for(int i = 0; i < sounds.Length; i++)
{
if(sounds[i].name == string.Empty)
{
continue;
}
list += (i.ToString() + ". " + sounds[i].name + "\n");
}
Debug.Log(list);
}
private void ListLoadedGameObjects()
{
Object[] gos = Resources.FindObjectsOfTypeAll(typeof(GameObject));
string list = string.Empty;
for(int i = 0; i < gos.Length; i++)
{
if(gos[i].name == string.Empty)
{
continue;
}
list += (i.ToString() + ". " + gos[i].name + "\n");
}
Debug.Log(list);
}
}
Finally, Resources.UnloadUnusedAssets() will only work if the asset is truly unused - that is, if there is no remaining script reference to the asset. If any Monobehavior is holding a reference, or if you have a link to a prefab that contains the asset, it will probably not be unloaded as a result of calling this. It is tricky to manage sometimes.
Hope this helps, and good luck!
Useful post - where do you get the numbers from for acceptable RA$$anonymous$$?
Those RA$$anonymous$$ values aren't from an authoritative source; just my own observations/forum research and then extrapolating for newer devices. I probably got the most data with ipad1, where we were constantly battling memory crashes.
In my idealized world, "too much memory" is receiving memory warnings from the os. In practice, I've occosionally had to let it slip ;).
Thanks for the detail - that's fine, observations are as valid as anything and we're seeing some signal 9 issues and running at about 80$$anonymous$$B I think. The trouble I am having at present is that the various metrics available give wildly different figures as to how much physical RA$$anonymous$$ is being used.
Our problem, I suspect, is that we have a memory intensive operation (compressing level data to save it between scenes) that allocates a lot of RA$$anonymous$$ during a blocking operation. I wonder if the application's main loop were allowed to run, whether Unity would handle the request more elegantly...
Yeah, I agree that the metrics given by the Unity profiler vs. the XCode profiler vs. a custom solution make it very hard to get an accurate picture of where your memory is going. I think this may be in part because Unity is pretty complicated, and it is storing things on the native heap vs. the mono heap. I've usually put more faith in the XCode profiler just because it is telling me what iOS is seeing, and iOS is the authority on whether my app gets ter$$anonymous$$ated or not.
I wrote a blog post on this awhile back which, frankly, could probably be expanded a bit more with info on profiling. If you're interested though, there may be some helpful info: http://supersegfault.com/?p=43
Your answer
Follow this Question
Related Questions
Several Memory Optimization Questions 0 Answers
Debugging crazy memory use & crash 1 Answer
Out of memory related to ProBuilder 2 Answers
Refreshing Crashes Web Player 0 Answers
Crash at Unity Startup (Stack Trace Shows "memcpy") 0 Answers