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.