Memory leak in SKTextureAtlas preloadWithCompletionHandler

Hi, I hope someone can help me find an answer to this problem. I filed a bug report to apple but they have not responded to my report yet. Please see the details below. If you have any questions regarding the problem, please feel free to post.


Summary: I created a test project (attached), and simply added the following code in touchUpAtPoint:

SKTextureAtlas* atlas = [SKTextureAtlas atlasNamed:@"GlobalMap"];

[atlas preloadWithCompletionHandler:^{

}];


I looked at instruments and it shows memory leaks whenever this method is called. It crashes eventually. I discovered this leak because in my ongoing game project, I preload several of my atlases at the beginning of the game. It started crashing when I updated my code to XCODE 8.0 and my iPhone to IOS 10.0


Steps to Reproduce:

1) Install the app in an iPhone

2) Run the app

3) touch the screen several times

4) monitor memory allocation and leaks


Expected Results: you will see memory leaks in instruments and memory allocation increases until the app crashes

Actual Results: I saw the expected results

Version: iOS 10.0.2

Configuration: iPhone 6

Replies

Do you have any debugging output set on your view? For example showsFPS. These have leaks in them I believe. If you are using them, trying commenting them out, and see if you still have a leak.


Cheers.

Thanks for the response. I do have showsFPS turned on, but when I comment out the preloadWithCompletionHandler line, I don't see any leaks.

Yes, but what about when you comment out showsFPS and the other debugging helpers? Do you still get the leak with preloadWithCompletionHandler back in your code?

Yes, the leaks are still there when I commented out the showsFPS, etc.

I can't believe no one's experiencing this and complaining about it? The bug report I filed is 28684035.


This is a pretty serious bug because my game sometimes crashes in loading time when all I do is call the preloadWithCompletionHandler method.

FWIW I feel like I am seeing similar behavior when I use SKTextureAtlas.preloadTextureAtlases(_:withCompletionHandler:). What I observe in Instruments is a gigantic volume of Leaks attributed to SpriteKit and the overall memory usage is roughly twice what I observe when I don't preload the atlases.


Here's what the output in Instruments looks like:


Leaked Object#SizeResponsible LibraryResponsible Frame
Malloc 12.09 MiB112.09 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 14.05 MiB114.05 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 14.05 MiB114.05 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.27 MiB113.27 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.33 MiB113.33 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.33 MiB113.33 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 14.05 MiB114.05 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.27 MiB113.27 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.17 MiB113.17 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.17 MiB113.17 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]
Malloc 13.27 MiB113.27 MiBSpriteKit-[SKTexture loadImageDataFromCGImage:pointsSize:]

Seems that while recommended, TAs have their limits. Quoting SO "...be aware that use of an atlas is not always the best approach. You can also save texture memory by decompressing and rendering at the same time, as described here: stackoverflow.com/a/38679128/763355"

It appears that this bug remains – I ran into it tonight on macOS Big Sur.

For now I've rolled my own preload by creating a sprite while the scene is faded out and cycling through my textures. It's a cheap hack, but it uses ~1GB less RAM than preloadWithTextures does.