- Home /
Instantiate fails on iPad. How can I debug memory allocation errors?
Currently my iPad app crashes in the middle of calling Instantiate. The line it fails on is this exact line (I have debug output before and after it). I can't replicate the crash on my mac in the editor.
Texture2D restore = UnityEngine.Object.Instantiate(undoData[currentIndex-1]) as Texture2D;
where undoData is an array of Texture2D objects and undoData[currentIndex-1] is not null (I've checked)
I initially thought that this could be to do with memory. I ran the internally iPad profiler which gave:
iPhone Unity internal profiler stats:
cpu-player> min: 7.7 max: 70.8 avg: 16.6
cpu-ogles-drv> min: 1.5 max: 3.0 avg: 1.8
cpu-waits-gpu> min: 0.2 max: 0.4 avg: 0.2
msaa-resolve> min: 0.0 max: 0.0 avg: 0.0
cpu-present> min: 0.5 max: 3.1 avg: 1.2
frametime> min: 30.3 max: 78.4 avg: 37.7
draw-call #> min: 28 max: 28 avg: 28 | batched: 0
tris #> min: 1566 max: 1566 avg: 1566 | batched: 0
verts #> min: 3140 max: 3140 avg: 3140 | batched: 0
player-detail> physx: 1.0 animation: 0.0 culling 0.0 skinning: 0.0 batching: 0.0 render: 1.8 fixed-update-count: 1 .. 4
mono-scripts> update: 13.2 fixedUpdate: 0.0 coroutines: 0.1
mono-memory> used heap: 3194880 allocated heap: 27750400 max number of collections: 0 collection total duration: 0.0
----------------------------------------
As you can see there is plenty of allocated space in the heap.
Is it possible that I have run out of video memory? Is there a way to check this? How could I go about debugging this problem?
Edit:
It definetly is a memory warning. I've been able to find a
WARNING -> applicationDidReceiveMemoryWarning()
message hidden further up above the profiler. This suggests that the used heap / allocated heap values don't reflect the full story and can't really be trusted :/
Update:
Problem solved - but why?
This problem was indeed caused by a memory leak. When replacing the texture on the material, I did not destroy the previous texture, which resulted in the replaced texture remaining in memory.
By calling:
Destroy( renderer.material.GetTexture ("_Texture2") );
before the replacement of the texture:
renderer.material.SetTexture("_Texture2", newTex);
Note that a memory warning was not always produced by the internal profiler.
I still don't understand why this occurs? Shouldn't the memory be collected by the garbage collecter once there are no references pointing to the old texture? Forcing GC.Collect() doesn't work either.
I removed my comments, finally i think that should work and i've no idea except what you've already mentioned...
Answer by Statement · Mar 13, 2011 at 01:30 AM
Shouldn't the memory be collected by the garbage collecter once there are no references pointing to the old texture?
Unity could internally keep a reference to the texture, so there is no guarantee.
I don't know iPads architecture but it is possible textures were maintained in special texture memory (video memory) that was running out, which might not be part of the heap/stack memory.