There is a memory explosion happening in my app. I have not found a way to reliably reproduce the explosion. From what I've seen, it can happen at any time, regardless of how long the app has been running.
I've been working on this problem for over three weeks.
My App has two principal ViewControllers. One to capture(captureVC) data using ARKit, and the other to display the captured data(ResultsVC) using SceneKit.
The CaptureVC also uses a CMMotionManager to capture the attitude of the phone.
Without getting too specific, the capture sessions are relatively short, and the user is allowed to engage in multiple sessions. Each completed session adds onto the visual data displayed in the ResultsVC.
I've set up handling for the didReceiveMemoryWarning notification in both VCs.
There are a couple of things that stick out to me in the memory debugger. Once I move to the ResultsVC after the first CaptureVC session, a retain cycle is getting reported in several places. You can see an example image of the retain cycle here.
The number of nodes in the retain cycle can vary from run to run, but there is always one or more CVObject and CVLocklessBunchPair. And there always seems to be just one CVPixelBufferPool.
Also I captured a memory graph of the explosion while I had Zombies turned on and there was an instance of ARImageDistortionCorrectionTechnique that pointed to the retain cycle.
That retain cycle is being reported as linked to either instances of NSMutableDictionary or IOSurface.
When the explosion happens, and the memory warning handlers get hit, and I go to the memory debugger, the only real indication that something has gone wrong is that there are an incredible amount of malloc blocks that have been allocated, like somewhere in the 3 million range. There also seem to be more instances of IOSurface in memory as well. But even with Malloc Stack backtracing turned on, I can't tell where any of the malloc blocks are coming from.
The main strategy I've employed is to make it so there are less instances of the code we maintain in memory at any given time. Especially if those instances inherit from the ARKit or SceneKit frameworks. I'm doing this with the hope that the likelihood of what seems like a crazy interaction between ARKit, SceneKit, and possibly CoreMotion, will be lessened if there are less objects in memory. I've achieved this lessening by declaring various members as weak. And turning a couple of classes into singletons.
I've made some headway in this direction, but the memory explosion is still happening. And the explosion can happen while either of the VCs is visible.
There is one clue that I have found. I've used XCode command line tools such as vmmap, and leaks, and I did see the term SurfaceDetectionNode_scheduler associated with a 1.8 GB region of allocated memory. But when I search for that term nothing related to iOS come up.
When I use the Leaks instrument, the CaptureVC will intermittently freeze, and trying to capture data in the CaptureVC becomes very time consuming. Trying to get the explosion to happen while the Leaks instrument is attached is like trying to hunt a unicorn with a spoon. I do have a couple of .trace files saved.
The people I took the app over from did not pay any attention to the memory usage of the app. So I'm assuming this is not a bug in ARKit or SceneKit.
It would be nice if there was a way to share memorygraph files here.
If anybody has any ideas, thank you so much!
I've been working on this problem for over three weeks.
My App has two principal ViewControllers. One to capture(captureVC) data using ARKit, and the other to display the captured data(ResultsVC) using SceneKit.
The CaptureVC also uses a CMMotionManager to capture the attitude of the phone.
Without getting too specific, the capture sessions are relatively short, and the user is allowed to engage in multiple sessions. Each completed session adds onto the visual data displayed in the ResultsVC.
I've set up handling for the didReceiveMemoryWarning notification in both VCs.
There are a couple of things that stick out to me in the memory debugger. Once I move to the ResultsVC after the first CaptureVC session, a retain cycle is getting reported in several places. You can see an example image of the retain cycle here.
The number of nodes in the retain cycle can vary from run to run, but there is always one or more CVObject and CVLocklessBunchPair. And there always seems to be just one CVPixelBufferPool.
Also I captured a memory graph of the explosion while I had Zombies turned on and there was an instance of ARImageDistortionCorrectionTechnique that pointed to the retain cycle.
That retain cycle is being reported as linked to either instances of NSMutableDictionary or IOSurface.
When the explosion happens, and the memory warning handlers get hit, and I go to the memory debugger, the only real indication that something has gone wrong is that there are an incredible amount of malloc blocks that have been allocated, like somewhere in the 3 million range. There also seem to be more instances of IOSurface in memory as well. But even with Malloc Stack backtracing turned on, I can't tell where any of the malloc blocks are coming from.
The main strategy I've employed is to make it so there are less instances of the code we maintain in memory at any given time. Especially if those instances inherit from the ARKit or SceneKit frameworks. I'm doing this with the hope that the likelihood of what seems like a crazy interaction between ARKit, SceneKit, and possibly CoreMotion, will be lessened if there are less objects in memory. I've achieved this lessening by declaring various members as weak. And turning a couple of classes into singletons.
I've made some headway in this direction, but the memory explosion is still happening. And the explosion can happen while either of the VCs is visible.
There is one clue that I have found. I've used XCode command line tools such as vmmap, and leaks, and I did see the term SurfaceDetectionNode_scheduler associated with a 1.8 GB region of allocated memory. But when I search for that term nothing related to iOS come up.
When I use the Leaks instrument, the CaptureVC will intermittently freeze, and trying to capture data in the CaptureVC becomes very time consuming. Trying to get the explosion to happen while the Leaks instrument is attached is like trying to hunt a unicorn with a spoon. I do have a couple of .trace files saved.
The people I took the app over from did not pay any attention to the memory usage of the app. So I'm assuming this is not a bug in ARKit or SceneKit.
It would be nice if there was a way to share memorygraph files here.
If anybody has any ideas, thank you so much!