领取MOLI红包

exception EXC

发布日期:2025-01-04 17:18    点击次数:91
一、问题:   直播助手在使用ReplayKit2 Extension的过程中,ReplayKit2的Upload进程工作在后台模式,苹果对处于后台的进程进行了内存和CPU资源的限制。   对于内存:     每种Extension的限制不同,ReplayKit2 Extension 的内存限制是 Active Memory limit = 50MB, 如果使用的物理内存超过这个限制,将会被系统直接干掉。(干掉之前会收到Memory Warning的警告)   对于CPU:     统计该进程一段时间内(300s)wakeup的次数,也就是线程切换调度的次数。     现象:   内存警告:      这个日志只能在Console中看到,对于用户而言,会收到一个弹框提示“某某进程中断”     CPU使用过多的现象:       二、问题分析   对于内存问题,目前尚无好的解决办法,苹果似乎在系统升级之后会调高限制的大小值,但是不多,不能解决根本问题。   本文主要对wakeups这个错误,CPU使用过多进行分析   1)苹果为什么要针对后台进程做这个限制?     过多的线程调度意味着繁忙得使用CPU,在移动设备上,频繁使用CPU将导致耗电量增大,电量消耗过快影响整个手机的使用。   2)是否能通过配置修改     目前查询到的信息是无法修改,已经在苹果的开发者论坛提交了一个反馈:     https://forums.developer.apple.com/message/332006#332006   3)线程切换是怎样造成的。     线程切换可能由于系统中断(系统调用带来)、主动的线程调度带来(sleep函数)带来。     这是之前的一份wakeup的记录,显示NSLog 和 stringwithformate 会带来线程切换。   NSLog可能比较好理解一点,因为NSLog不仅仅将log输出到控制台,还会将log输出(通过Socket)到远程的Console端口,Mac上的Console App能收到手机的Log就是这个原因。   根据glibc系统调用列表,socket中的操作都会走到系统调用中         对于stringWithFormate而言,格式化输出了一个字符串,也很可能走到malloc的系统调用中,这里猜测一下:    为了验证猜测,编写测试代码:         代码比较简单,其中有一个Swift的字符串的格式化。其内部的实现会走到 __CFStringAppendFormatCore 方法中,这个和OC 这边的格式化方法是一致的。       上面的堆栈也能清楚看出来。   为了验证猜测,我下一个malloc的符号断点:      然后跑一下程序,果然断下来了      果然调用到了malloc,说明格式化字符串会产生内存分配的系统调用,从而导致线程切换。   4)优化方向   观察我们的助手log的输出,1s之内输出了一百多条的log      由此找到了一个方方向,减少输出log的系统调用。   5)优化     待完成   三、附录   1)系统调用列表:https://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html   2)malloc 原理 -os-knowledge/   3)上一篇wakeups https://www.cnblogs.com/doudouyoutang/p/7610982.html   4)https://stackoverflow.com/questions/45511944/ios-how-to-measure-thread-wakeups   5)https://forums.developer.apple.com/message/332006#332006   6)https://www.theiphonewiki.com/wiki/Kernel_Syscalls