一次 “卡顿” 的优化
最近因为有赛事,用户量一下子暴涨,然后 crash 率也暴涨,同时还有大量用户反馈卡顿,花了大量时间进行定位和优化,这里做一下总结。
离开 Profile 谈优化都是耍流氓。首先是从卡顿入手,在用Time Profiler圈出卡顿时段,点开主线程发现只有系统的函数。 然后怀疑到内存问题,要么是泄漏要么是占用过高。然后挂起了 Allocations 测试内存。跑了接近20分钟,看图:

可以看到 CFString 占用非常高,点开发现是 FMDB 用的,并且没有泄漏。

那就肯定是没有触发释放时机了。为啥呢?这个要从 mrc 年代说起。当年的引用计数是手动管理的,我们自己调用了一次 alloc,
(或者名字带有 alloc 的方法),就需要自己调用一次 release,而这种 stringWithFormat: lowercaseStringWithLocale:
这种方法是在库函数里面分配的,不需要主动调 release,实际上它的分配是这样的:[[[NSString alloc] init] autorelease]
然后 autorelease 会在 autorelease pool 释放的时候一起释放。每一个线程都会有一个 autorelease pool,我们是在
一个测试的死循环线程里面处理的消息,这个线程是没有机会被释放的。

结论就是,在被测试方法增加一个 @autoreleasepool,然后再定位新的问题。 待续。。。
— 更新 —
后面定位内存问题,处理了部分自己的内存泄漏,大多数是block使用不当,还有部分是第三方组件,例如云通信自己的,随着使用时间增长, 发现他们内部占用内存也会越来越高,怀疑是占用的内存没来得及释放,已经给他们反馈。别的SDK也有部分泄漏能更新的更新了处理,不能更新的自己改掉。