Search code examples
macosmemoryscenekitscnskinner

SCNSkinner.boneIndices access generates GBytes of memory allocation - why?


I have an app that analyses the bones influence over vertices. For this I go through a SCNSkinner boneIndices data in a loop, and, though I don't allocate memory inside this loop, GBytes of memories are allocated, resulting in a crash of the app.

I have traced crashes to be linked to access to boneIndices using Instruments the following way:

  1. See that memory is being allocated in a crazy way (here, 15GBytes in about 5 seconds): enter image description here

  2. Click on this "Malloc 224k" to see that they are all performed in a single method. enter image description here

  3. Click on the method name, and the tools clearly blames access to .boneIndices. enter image description here

As you can notice, this is Objective-C code (this is a category on SCNSkinner), but I observed the same with a Swift translation.

Why is every read access to SCNSkinner.boneIndices (read only) generating some memory allocation ?

What is the trick to avoid that ? (basically I only want to read that buffer).

PS1: I observed that on macOS 14.2.1 - I haven't verified on iOS.

PS2: You can also see that an access to .bones generated 352 bytes of allocation, which I can easily live with, but still, it is surprising that accessing SCNSkinner properties to read them generates so much allocation.


Solution

  • Retrieving a skinner's bones or boneIndices is likely returning autoreleased NSArray instances. If done in a tight loop this can lead to important memory pressure as reported here by Instruments.

    The fix is simple: store self.boneIndices in a local variable before the nested loops so that there's only 1 NSArray allocation.