iOS(OC+cocos2dx)游戏APP磁盘空间爆增(文稿与数据)

这段时间在开发公司的新产品二次元游戏(零下记忆),由于接触coco2dx不久,很多东西还在摸索,也没少加班,所以都没有时间整理和发文了。

但是最近(从周一开始),发现了一个特别其他的Bug,App磁盘数据报增,幸好我手机是64G的,不然估计会爆炸!

先来张爆图!

曹理鹏(iCocos)-梦工厂

这个产品是在Objective-C原生架构的基础上接入cocos2dx(C++),所以导致部分文件或者类需要使用MRC模式。

我曾尝试过
  1. 使用模拟器针对不同时段操作,计算沙盒文件大小。
  2. 借助部门同事的越狱机导包寻找导致爆增的具体文件。
  3. 多次删除App,关闭可能存在问题原因的代码。
  4. 借助内存泄漏框架自动记录,内存变化与位置。
  5. 借助Xcode自带Instrument定点查找具体位置和代码。
  6. 通过Stack Overflow查询更多可能导致的原因。

经过一次次排查,和一个个问题的处理,最终通过多次杀进程,和运行测试,终于处理完成,不过还有待优化!

下面是具体原因和流程。

清理缓存:

清理cocos2dx缓存:
1
2
3
4
5
6
7
8
9
CCAnimationCache::purgeSharedAnimationCache();
CCSpriteFrameCache::purgeSharedSpriteFrameCache();
CCTextureCache::purgeSharedTextureCache();

CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();
CCTextureCache::sharedTextureCache()->removeUnusedTextures();
CCTextureCache::sharedTextureCache()->removeAllTextures();

Director::getInstance()->getTextureCache()->removeAllTextures();
清理运行磁盘,内存或者缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
+ (void)clearAllCache {
[[SDImageCache sharedImageCache] clearMemory];
[[SDImageCache sharedImageCache] clearDiskOnCompletion:nil];
// 拿到cachePath路径的下一级目录的子文件夹
// contentsOfDirectoryAtPath:error:递归
// subpathsAtPath:不递归
NSArray *subpathArray = [fileManager contentsOfDirectoryAtPath:cachePath error:nil];
// 如果数组为空,说明没有缓存或者用户已经清理过,此时直接return
if (subpathArray.count == 0) {
#ifdef DEBUG
NSLog(@"cachePath缓存清理完成");
#else

#endif
}
NSError *error = nil;
NSString *filePath = nil;
BOOL flag = NO;
for (NSString *subpath in subpathArray) {
filePath = [cachePath stringByAppendingPathComponent:subpath];
if ([fileManager fileExistsAtPath:cachePath]) {
// 删除子文件夹
BOOL isRemoveSuccessed = [fileManager removeItemAtPath:filePath error:&error];
if (isRemoveSuccessed) { // 删除成功
flag = YES;
}
}
}
if (NO == flag) {
#ifdef DEBUG
NSLog(@"已经清理了所有可以访问的文件,不可访问的文件无法删除"); // 调试阶段才打印
#else

#endif
}
}

记忆中此处大概处理了1-3G

内存管理

通过Stack Overflow和相应代码调试最后发现:

原来是把sprite和控件都retain了,需要手动release,才能释放图片。

所以我得找到对应的cocos2dx项目代码,对创建和操作的对象进行release操作,这里比较蛋疼,得一个个找!

  • 处理中遇到个问题:
    • removeTexture执行release后,不管有没有被gl释放掉,都从列表里删除。

但是如果load进来的node被addChild到场景中,应该是不需要retain的,addChild会自动retain,这里不清楚,cocos2dx引擎设计者在load里加retain是为了什么,

这里所导致的问题,几乎是使用过程中内存暴涨

环境与配置(主要原因):

通过多次测试发现沙盒文件中的temp中有一堆文件stack-logs.xxxxx.index

曹理鹏(iCocos)-梦工厂

  • 同时控制台也打印了一大堆看不懂也搜不到的内容

曹理鹏(iCocos)-梦工厂

结合以上几点才初步猜测可能是因为配置环境的问题,查阅资料后发现这与Xcode设置有关,具体配置原因我也不记得了,印象中是当时配置接入cocos2dx的时候,遇到了一些问题,点过了一次,但是现在想想好像当时的操作并没有什么卵用!

  • Edit Scheme中Diagnostics有个logging分类,下面有个Malloc Stack选项,将勾选取消。

曹理鹏(iCocos)-梦工厂

处理完后立刻验证了一下,重装App,多次执行杀进程和实际测试用,在tmp下并没有产生那个文件stack-logs.xxxxx.index,磁盘占用也处于稳定状态,再打开手机设置查看存储空间,也很正常。

曹理鹏(iCocos)-梦工厂

以上文稿与数据的15.7中有13M多属于App下载的资源文件。

That’s all for today.

坚持原创技术分享,您的支持将鼓励我继续创作!