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:
See that memory is being allocated in a crazy way (here, 15GBytes in about 5 seconds):
Click on this "Malloc 224k" to see that they are all performed in a single method.
Click on the method name, and the tools clearly blames access to .boneIndices
.
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.
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.