最近在看FOOM,翻译一下facebook的解决方案。
原文链接在Facebook iOS app中减少FOOMs

在Facebook iOS app中减少FOOMs


在Facebook,我们致力于使我们的应用程序稳定、快速和可靠。我们一直在努力减少Facebook IOS应用中的崩溃次数,并提高其整体的可靠性。过去,大多数crash是由于程序错误引起的,并且它们总是带有可以定位错误的堆栈和一直提供crash根源的提示。

随着我们不断修复Crash问题,我们观察到Crash率不断下降,但是从App Store的评论中我们注意到社区仍然对应用crash感到崩溃。我们深入研究了用户报告,和开始推断可能发生了OOM(out of memory)。当系统内存不足时,操作系统会终止应用程序以回收内存时,会发生OOM。无论应用程序在前台还是在后台,都可能发生OOM。我们在内部分别将它们称为FOOMs和BOOMs——可以说应用程序发生BOOM是有点有趣的。

从用户的角度来看,前台OOM(FOOM)与Crash是无法区分的。在这两种情况下,应用都会意外终止,出现消失和用户被带回到设备的主屏幕。如果内存消耗率急剧增加,则应用程序被杀死而不会收到任何有关内存用尽的信号。在IOS上,操作系统会尽力向应用程序发送内存警告,但不能保证在操作系统退出进程之前始终收到警告。这使我们无法轻松知道该应用由于内存不足而被操作系统杀死。

处理问题

为了了解我们的应用由于OOM Crash而闪退的频率,我们首先枚举了可以终止应用的所有已知路径,然后对其进行记录。我们研究的问题是“什么导致应用程序启动?”

应用可能由于以下原因需要启动:

  • 程序是否升级
  • 程序是否调用exit()和abort()
  • 程序是否crash
  • 用户向上滑动强制退出应用程序
  • 设备重启(包括操作系统升级)
  • 程序在后台或前台内存不足(OOM)

通过排除法,寻找不属于其他情况的实例,然后我们可以确定何时发生OOM。同时我们也跟踪应用程序是否在前台还是后台,以便我们可以准确的将OOM分解为BOOMs和FOOMs。

日志记录表明,内存较少的设备上的OOM发生率较高,这是可以预期的并且令人放心的,因为应用程序更有可能在受限内存的设备上退出。看到日志记录中的相关性有助于我们验证排除的实例是否正确并继续改进日志(我们最初并未识别所有情况,例如应用程序升级)。

我们减少OOM的数量的第一个尝试是尽可能回收应用程序不在需要的内存。不幸的是,我们观察到OOM崩溃的次数并没有变化。因此我们将重点转移到了大的内存分配上。首先是可能泄漏的内存(未清理过),尤其是通过潜在的保留周期。

分析内存使用情况

当我们开始修复内存泄漏时,我们看到OOM率有所降低,但是我们仍然没有看到我们希望的显著降低。接下来,我们深入研究了Apple的Instruments 应用程序中的内存分析器和注意到一旦应用程序打开任何页面,UIWebView就会重复分配大量内存。我们还发现,即使用户关闭web视图离开页面后,也常常无法回收内存。
我们尝试了许多优化措施,例如清理缓存和清理内容,但是导航到Web视图后,我们应用程序进程的内存占用始终显著增加。iOS 8引入了一个新类WKWebView,该类实际上是在一个单独的进程中执行其大部分工作,这意味着大多数与Web视图相关的内存使用情况不会统计到我们的进程。在内存不足的情况下,web视图的进程可能会被杀死,而我们的应用程序更有可能继续运行。在将应用程序迁移到WKWebView之后,我们确实看到了应用程序中的OOM的显著减少。Yay!

内存分配率

通过Instruments进行内存使用情况分析时,我们还观察到应用程序使用内存情况的某些实例,在这些实例中,应用程序临时分配了大量内存(约30M),不久后释放。如果在此分配过程中CPU不空闲,则OS可能会杀死该应用程序。如果我们能够摆脱这些临时分配,这有助于在某些情况下将OOM减少多达30%。我们还进行了试验和发现一次性分配并保留到内存中对于提高应用程序的稳定性要比重复分配和释放更好。

阻止回归

即使迁移到WKWebView之后,我们仍然发现较小的内存泄漏也可能会明显影响OOM率,尤其是在内存受限的设备上。由于我们频繁的发布计划,并且有许多团队贡献代码到应用程序中。因此捕获并防止我们发布的应用程序内存泄漏是重要的。我们利用了最初用于测试移动性能的 CT-Scan infrastructure来记录进程中的常驻内存量(测试左移),允许CT-Scan在代码被引进的时候就对回归量(内存)进行标记。这会帮助我们在开始工作时将OOM率保持较低水平。

内置的APP内存分析器

我们在工程中使用的最后一个关键策略是构造一个内置的App内存分析器。该分析器通过追踪所有Objective-C对象的分配来快速对应用程序进行性能分析。我们在CT-Scan和应用程序的内部版本中进行了配置。

它的工作原理如下:对于系统中的每个类,它会计数当前有多少个存活实例。我们可以随时查询它,并记录每个类的当前对象数。然后,我们可以分析此数据的每个发布版本以识别应用程序整体分配模式的变化,通常当计数急剧变化时可以帮助我们识别是否内存泄漏。我们设计了一种足够有效的方法来实现,从而不会对用户的应用程序性能产生任何明显的影响。

这是我们的策略以及如何跟踪NSObject分配的示意图。

我们首先创建了一个内存分配跟踪器类。它非常简单,该跟踪器会将类名和实例计数器进行映射,以及增加和减少计数的公共方法。我们选择使用C++而不是Objective-C,以便将跟踪器的所有内存分配和Cpu开销保持在最低水平。

class AllocationTracker {static AllocationTracker* tracker();void incrementInstanceCountForClass(Class aCls);void decrementInstanceCountForClass(Class aCls);std::vector<std::pair<Class, unsigned long long>> countsSnapshot();...
}

然后我们使用ios方法替换(叫做“swizzling,” 使用运行时函数class_replaceMethod)将标准的IOS方法+alloc 和 +dealloc替换为方法–fb_originalAlloc 和 –fb_originalDealloc.

然后,我们用新的实现替换
+alloc 和 +dealloc。这些实现分别会增加和减少分配和释放的实例数量

@implementation NSObject (AllocationTracker)+ (id)fb_newAlloc
{id object = [self fb_originalAlloc];AllocationTracker::tracker()->incrementInstanceCountForClass([object class]);return object;
}- (void)fb_newDealloc
{AllocationTracker::tracker()->decrementInstanceCountForClass([object class]);[self fb_originalDealloc];
}@end

然后,当应用程序运行时,我们可以定期调用快照方法以记录当前存活实例数量

App稳定性很重要

当我们推出了解决Facebook iOS应用程序中内存问题的方法时,我们发现(F)OOMs以及应用程序crash的用户报告数量都大大减少了。OOM崩溃对我们是一个盲点,因为没有正式的系统或API可以观察OOM事件及其发生的频率。当应用突然闪退时,没有人喜欢它。借助一些工具,向最新的iOS技术迁移,以及在最开始的时候就尝试解决这个问题(测试左移)也是可以借鉴的,我们能够使我们的应用程序更加可靠,并确保在打开Web视图时不会突然关闭应用程序。

还要感谢Linji Yang,Anoop Chaurasiya,Flynn Heiss,Parthiv Patel,Justin Pasqualini,Cloud Xu,Gautham Badrinathan,Ari Grant和其他许多人,他们帮助降低了FOOM率。

副业赚钱

说完了正文,接下来打一波广告,程序员如何副业赚钱,我本科同学这里有一个赚钱的机会,现在是北大金融系硕士,有副业赚钱想法的兄弟们,请添加他微信 zhengxiangpku 备注lfdanding推荐 即可。

在Facebook iOS app中减少FOOMs相关推荐

  1. 在你的 iOS App中 使用 OpenSSL 库 转发

    在你的 iOS App中 使用 OpenSSL 库 转发 英文原文链接:http://www.x2on.de/2010/07/13/tutorial-iphone-app-with-compiled- ...

  2. php图片涂鸦,IOS_详解iOS App中图片的线段涂鸦功能的添加方法,接下来我们要讲图片的涂鸦, - phpStudy...

    详解iOS App中图片的线段涂鸦功能的添加方法 接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线 创建项目 起名testAddLine 接下来我们在默认生成的ViewControlle ...

  3. 快速获取iOS APP中的所有素材

    2019独角兽企业重金招聘Python工程师标准>>> 1.我们都知道最常规的获取app中的素材是通过iTunes下载应用 -> 右键show in Finder获取ipa文件 ...

  4. 苹果官方要求在iOS App中提供帐户删除选项

    背景情况 最近发布iOS应用到市场时,在审核阶段被官方打回. 查看原因惊讶地发现,审核团队竟然说缺少账号删除功能? 经过一番百度搜索后,才发现官方又有新的审核政策,那就是要求在2022年6月30号之后 ...

  5. iOS app中不能跳转到商店更新

    文章目录 问题:跳转没有反应 延申说明 问题:跳转没有反应 如果app在苹果商店中的访问地址中带有中文,直接使用带中文url是跳转不成功的,需要对这个带中文的url进行UrlEncode编码才能正常跳 ...

  6. iOS APP中嵌入网速监测功能

    企鹅的手机管家.一些网页都提供了网速监测功能.在开发过程中我们偶尔也需要开发这个模块,以提示用户网速的状况,增强用户体验. 常见的网络测速方案 通过调研发现,目前常见的网络测速方案只有两种: 方案1: ...

  7. ios html 全屏播放,iOS APP 中H5视频默认全屏播放问题解决

    问题描述:在Android中,视频可以正常在H5页面局部播放,iOS中则自动切换至全屏模式. 查看资料得以解决,20190301记录下来. 解决方法:IOS10及以后,在 video标签页中只包含 w ...

  8. iOS APP 中H5视频默认全屏播放

    问题描述:在Android中,视频可以正常在H5页面局部播放,iOS中则自动切换至全屏模式,需要禁止视频自动全屏播放. 解决方法: H5端: iOS10以上H5视频不自动全屏播放识别 playsinl ...

  9. timerpickerview使用_详解iOS App中UIPickerView滚动选择栏的添加方法

    1.UIPickerView的宽度和高度是固定的,纵向是320216,横向是568162 2.属性: @property(nonatomic,readonly)NSInteger numberOfCo ...

最新文章

  1. 爬取网页时自动获取网页编码信息,并对特殊的乱码页面(压缩过的网页内容)用gzip进行解码。...
  2. BUAA_OO_第二单元作业总结
  3. 根据url提取网站域名的方法小结
  4. 平衡二叉查找树的构造与遍历(C++)
  5. 【每日算法Day 72】谷歌面试题:又双叒叕是位运算,最详细的自动机推导过程...
  6. 1算法:控制字幕左右移动
  7. Premiere 视频基本调色
  8. df.to_csv输出结果隔行多一个空行的解决办法
  9. Unity (三) NavMeshAgent之:分层路面导航(王者荣耀,英雄联盟中小兵分三路进攻敌方)...
  10. OpenCV(三)彩色图灰度化、通道分离、单通道反差处理(灰度图)、多通道反差处理(彩色图)
  11. 机械--NX2007(UG)--间隙分析(干涉检查)
  12. 小满网络模型http1-http2 浏览器缓存
  13. 一个网站的pv代表什么?
  14. 手机App开发的基础概念
  15. 什么是数字化?企业如何实现数字化?
  16. YYModel 简介与使用
  17. Linux 设备树(Device Tree)简介
  18. 三大流行BI分析平台推荐,企业数据化选择工具
  19. 微信小程序头像上传+(C#)服务端接收
  20. word论文计算机,计算机网络专业毕业论文 Microsoft Word 文档.doc

热门文章

  1. 信息家电嵌入式软件技术框架
  2. 网络分流器-网络分流器-5G的关键技术第一篇
  3. Excel格子画_Mickey Mouse
  4. Blender 物理属性 (三)力场
  5. 关于kernel-power带来的的反复死亡
  6. Oracle Business Intelligence Foundation 12c sample app虚拟机下载和使用
  7. Windows下配置QtXlsx
  8. 自助洗车APP开发基本功能需求
  9. 南京师范大学计算机技术学院,南京师范大学计算机与电子信息学院
  10. 修改el-form制作自定义元素登录框