SpriteKit SKTextureAtlas,由于加载纹理时的内存压力而终止 [英] SpriteKit SKTextureAtlas, Terminated Due to Memory Pressure while loading texture

查看:113
本文介绍了SpriteKit SKTextureAtlas,由于加载纹理时的内存压力而终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似于WWDC的SpriteKit特色游戏冒险",我尝试通过图块加载我的背景图片.我创建了一个纹理图集,其中包含6300个平铺",每个平铺大小为100x100像素.完整的背景图像总计为30,000x2048(用于视网膜显示).这个想法是背景将从右向左移动(侧滚动).第一列和最后一列匹配,因此它们看起来是连续的.

Similar to the SpriteKit Featured Game "Adventure" from WWDC, I am try to load my background image via tiles. I have created a Texture Atlas that contains 6,300 "tiles" that are each 100x100 pixels in size. The complete background image is a total of 30,000x2048 (for retina displays). The idea is that the background will move from right to left (side-scroller). The first column and the last column match so that they seem continuous.

运行该应用程序时,它将在我的内存"选项卡中加载我的初始加载屏幕和标题图像,并且峰值达到 54MB ,CPU使用率为 16%.在选择菜单级别之前,这与我浏览菜单相同,它告诉后台线程加载级别资产(其中包含上述背景图像).整个.atlas文件夹显示仅为 35.4MB .我不认为这是个问题,因为Adventure .atlas文件夹(来自WWDC)显示仅为 32.7MB .

When the application runs, it loads my initial loading screen and title images and spikes to 54MB in my memory tab with a CPU usage of 16%. This stays the same as I navigate through the menus until I choose my level, which tells a background thread to load the level assets (of which contains the aforementioned background image). The entire .atlas folder shows to be only 35.4MB. I don't believe that this is a problem since the Adventure .atlas folder (from WWDC) shows to be only 32.7MB.

选择级别后,在开始接收内存警告之前,它将在.atlas文件夹中加载大约20个纹理,并使应用程序崩溃.我已经检查了仪器是否泄漏,它没有显示任何内存泄漏.我没有收到任何编译器错误(甚至没有EXC_BAD_ACCESS错误).我查看了我的设备控制台,发现了应用程序崩溃的几行内容,但对我而言似乎并没有多大意义.我还检查了僵尸,但似乎没有找到任何僵尸.

Once I select the level, it loads approximately 20 of the textures in the .atlas folder before I start receiving memory warnings and it crashes the application. I've checked in Instruments for leaks and it doesn't show any memory leaks. I don't receive any compiler errors (not even the EXC_BAD_ACCESS one). I've looked at my device console and have found a few lines of where the application crashes, but it doesn't look to make much sense to me. I've also checked for Zombies, but haven't seemed to find any.

CoreLevel.m

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // Used to determine time spent to load
    NSDate *startDate = [NSDate date];

    // Atlas to load
    SKTextureAtlas *tileAtlas = [SKTextureAtlas atlasNamed:@"Day"];

    // Make sure the array is empty, before storing the tiles
    sBackgroundTiles = nil;
    sBackgroundTiles = [[NSMutableArray alloc] initWithCapacity:6300];

    // For each row (21 Totals Rows)
    for (int y = 0; y < 21; y++) {

        // For each Column (100 Total Columns)
        for (int x = 1; x <= 100; x++) {

            // Get the tile number (0 * 32) + 0;
            int tileNumber = (y * 300) + x;

            // Create a SpriteNode of that tile
            SKSpriteNode *tileNode = [SKSpriteNode spriteNodeWithTexture:[tileAtlas               textureNamed:[NSString stringWithFormat:@"tile_%d.png", tileNumber]]];

            // Position the SpriteNode
            CGPoint position = CGPointMake((x * 100), (y * 100));
            tileNode.position = position;

            // At layer
            tileNode.zPosition = -1.0f;
            tileNode.blendMode = SKBlendModeReplace;

            // Add to array
            [(NSMutableArray *)sBackgroundTiles addObject:tileNode];
        }
    }
    NSLog(@"Loaded all world tiles in %f seconds", [[NSDate date] timeIntervalSinceDate:startDate]);
});

这似乎与调试控制台中的崩溃有关:

This is what seems to pertain to the crash from the Debug console:

com.apple.debugserver-300.2[9438] <Warning>: 1 +0.000000 sec [24de/1807]: error: ::read ( -1, 0x4069ec, 18446744069414585344 ) => -1 err = Bad file descriptor (0x00000009)
com.apple.debugserver-300.2[9438] <Warning>: Exiting.
com.apple.launchd[1] (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d][9441]) <Notice>:     (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d]) Exited: Killed: 9

我没有足够的声誉来发布图像,因此,这里有指向我在Instruments中分配的屏幕截图的链接:

I don't have enough reputation to post images so here is a link to a screenshot screenshot of my allocations in Instruments:

http://postimg.org/image/j17xl39et/

非常感谢您的帮助和建议!如果我遗漏了一些相关信息,我很高兴进行更新.

Any help and advice is much appreciated! If I've left out some pertinent information, I'm glad to update.

推荐答案

图像文件(PNG,JPG,Atlas文件夹等)的文件大小不会告诉您有关内存的使用情况.

The file size of an image file (PNG, JPG, atlas folder, etc) tells you nothing about the memory usage.

相反,您必须使用以下公式计算纹理内存的使用量:

Instead you have to calculate the texture memory usage using the formula:

width * height * (color bit depth / 8) = texture size in bytes

例如,尺寸为4096x4096像素和32位色深(4字节)的图像在作为纹理(未压缩)加载时使用了这么多的内存:

For example an image with dimensions 4096x4096 pixels and 32 bits color depth (4 bytes) uses this much memory when loaded as a texture (uncompressed):

4096 * 4096 * 4 = 67108864 bytes (64 Megabytes)

根据您的规格(假设它们都是唯一的,共有6,300个图块,每个100x100像素,假设它们都是唯一的),yyyyyy高于纹理内存使用的任何合理限制(约1.5 GB!).考虑到地图集大小为35兆字节(对于地图集btw是巨大),并假设压缩比仅为10:1,您可能仍会看到350+兆字节的纹理内存使用情况.

According to your specs (6,300 tiles, each 100x100 pixels, assuming they're all unique) you're way, wayyyyyy above any reasonable limit for texture memory usage (about 1.5 Gigabytes!). Considering the atlas size of 35 Megabytes (which is huge for an atlas btw) and assuming a mere 10:1 compression ratio you may still be looking at 350+ Megabytes of texture memory usage.

这篇关于SpriteKit SKTextureAtlas,由于加载纹理时的内存压力而终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆