Scene Kit Memory Management Using Swift

scene kit memory management using swift

So I found out what I needed to do was set the texture on my game objects to nil before removing them from the parent. Just as a general rule, I started setting all my textures to nil before deleting the node. Anyway, this solved my memory problem.

Managing memory in Swift (SceneKit game)

I also meet the same case.And I find a solution to fix the bug.You must asynchronous to remove and release scnView.Just look the following code.

    _scnView.antialiasingMode = SCNAntialiasingModeNone;
__block SCNView *strongScnView = _scnView;
_scnView = nil;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[strongScnView setScene:nil];
[strongScnView removeFromSuperview];
[strongScnView stop:nil];
strongScnView = nil;
});

SceneKit: too much memory persisting

Spheres, capsules, and cylinders all have fairly dense meshes. Do you need all that detail? Try reducing the various segment count properties (segmentCount, radialSegmentCount, etc). As a quick test, substitute SCNPyramid for all of your primitive types (that's the primitive with the lowest vector count). You should see a dramatic reduction in memory use if this is a factor (it will look ugly, but will give you immediate feedback on whether you're on a usable track). Can you use a long SCNBox instead of a cylinder?

Another optimization step would be to use SCNLevelOfDetail to allow substitute, low vertex count geometry when an object is far away. That would be more work than simply reducing the segment counts uniformly, but would pay off if you sometimes need greater detail.

Instead of managing the components yourself in arrays, use the node hierarchy to do that. Create each molecule, or animatable piece of a molecule, as a tree of SCNNodes. Give it a name. Make a flattenedClone. Now archive that. Read the node tree from archive when you need it; don't worry about arrays of nodes.

Consider writing two programs. One is your iOS program that manipulates/displays the molecules. The other is a Mac (or iOS?) program that generates your molecule node trees and archives them. That will give you a bunch of SCNNode tree archives that you can embed, as resources, in your display program, with no on-the-fly generation.

An answer to scene kit memory management using swift notes the need to nil out "textures" (materials or firstMaterial properties?) to release the node. Seems worth a look, although since you're just using UIColor I doubt it's a factor.

Here's an example of creating a compound node and archiving it. In real code you'd separate the archiving from the creation. Note also the use of a long skinny box to simulate a line. Try a chamfer radius of 0!

extension SCNNode {

public class func gizmoNode(axisLength: CGFloat) -> SCNNode {
let offset = CGFloat(axisLength/2.0)
let axisSide = CGFloat(0.1)
let chamferRadius = CGFloat(axisSide)

let xBox = SCNBox(width: axisLength, height: axisSide, length: axisSide, chamferRadius: chamferRadius)
xBox.firstMaterial?.diffuse.contents = NSColor.redColor()
let yBox = SCNBox(width: axisSide, height: axisLength, length: axisSide, chamferRadius: chamferRadius)
yBox.firstMaterial?.diffuse.contents = NSColor.greenColor()
let zBox = SCNBox(width: axisSide, height: axisSide, length: axisLength, chamferRadius: chamferRadius)
zBox.firstMaterial?.diffuse.contents = NSColor.blueColor()
let xNode = SCNNode(geometry: xBox)
xNode.name = "X axis"
let yNode = SCNNode(geometry: yBox)
yNode.name = "Y axis"
let zNode = SCNNode(geometry: zBox)
zNode.name = "Z axis"

let result = SCNNode()
result.name = "Gizmo"
result.addChildNode(xNode)
result.addChildNode(yNode)
result.addChildNode(zNode)
xNode.position.x = offset
yNode.position.y = offset
zNode.position.z = offset

let data = NSKeyedArchiver.archivedDataWithRootObject(result)
let filename = "gizmo"

// Save data to file
let DocumentDirURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)

// made the extension "plist" so you can easily inspect it by opening in Finder. Could just as well be "scn" or "node"
// ".scn" can be opened in the Xcode Scene Editor
let fileURL = DocumentDirURL.URLByAppendingPathComponent(filename).URLByAppendingPathExtension("plist")
print("FilePath:", fileURL.path)

if (!data.writeToURL(fileURL, atomically: true)) {
print("oops")
}
return result
}
}

SpriteKit Memory increase every time new scene presented

I tried checking if things had not been deallocated and this did not solve the problem. I used a developer technical support ticket and an engineer advised me to turn off "GPU Frame Capture" in the scheme for the project.

This 95% solved the problem. Memory usage has reduced to a lot more reasonable amount and the app no longer continues to build up memory usage after I implement reasonable methods to deallocate scenes, nodes etc...

I asked if this solution was only for testing in Xcode and I was told it was not, this is how my app will perform on the App Store:

"GPU Frame Capture is a tool for debugging and is only present when running your app with the Xcode Debugger attached!" - Said the engineer.

SpriteKit retaining memory after I leave game

Based on your comments, you should use capture lists:

func createHerosAction(duration: Double = 5.0){

run(SKAction.repeatForever(
SKAction.sequence([

SKAction.run {[unowned self] in
self.addHero()
},
SKAction.wait(forDuration: duration)
])
), withKey:"createHeros")
}

It is a big topic, but I suggest you to start reading the link I have posted, because it has everything explained in detail starting from "How ARC works", "What are Capture Lists" to the weak and unowned keywords. I wrote few times about this already, as well as many others on this site, and it is a big topic, so I will skip that this time :)



Related Topics



Leave a reply



Submit