iOS开发高手课
戴铭
前滴滴出行技术专家
立即订阅
11450 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 锚定一个点,然后在这个点上深耕
免费
基础篇 (20讲)
01 | 建立你自己的iOS开发知识体系
02 | App 启动速度怎么做优化与监控?
03 | Auto Layout 是怎么进行自动布局的,性能如何?
04 | 项目大了人员多了,架构怎么设计更合理?
05 | 链接器:符号是怎么绑定到地址上的?
06 | App 如何通过注入动态库的方式实现极速编译调试?
07 | Clang、Infer 和 OCLint ,我们应该使用谁来做静态分析?
08 | 如何利用 Clang 为 App 提质?
09 | 无侵入的埋点方案如何实现?
10 | 包大小:如何从资源和代码层面实现全方位瘦身?
11 | 热点问题答疑(一):基础模块问题答疑
12 | iOS 崩溃千奇百怪,如何全面监控?
13 | 如何利用 RunLoop 原理去监控卡顿?
14 | 临近 OOM,如何获取详细内存分配信息,分析内存问题?
15 | 日志监控:怎样获取 App 中的全量日志?
16 | 性能监控:衡量 App 质量的那把尺
17 | 远超你想象的多线程的那些坑
18 | 怎么减少 App 电量消耗?
19 | 热点问题答疑(二):基础模块问题答疑
20 | iOS开发的最佳学习路径是什么?
应用开发篇 (12讲)
21 | 除了 Cocoa,iOS还可以用哪些 GUI 框架开发?
22 | 细说 iOS 响应式框架变迁,哪些思想可以为我所用?
23 | 如何构造酷炫的物理效果和过场动画效果?
24 | A/B 测试:验证决策效果的利器
25 | 怎样构建底层的发布和订阅事件总线?
26 | 如何提高 JSON 解析的性能?
27 | 如何用 Flexbox 思路开发?跟自动布局比,Flexbox 好在哪?
28 | 怎么应对各种富文本表现需求?
29 | 如何在 iOS 中进行面向测试驱动开发和面向行为驱动开发?
30 | 如何制定一套适合自己团队的 iOS 编码规范?
31 | iOS 开发学习资料和书单推荐
32 | 热点问题答疑(三)
原理篇 (6讲)
33 | iOS 系统内核 XNU:App 如何加载?
34 | iOS 黑魔法 Runtime Method Swizzling 背后的原理
35 | libffi:动态调用和定义 C 函数
36 | iOS 是怎么管理内存的?
37 | 如何编写 Clang 插件?
38 | 热点问题答疑(四)
原生与前端共舞 (5讲)
39 | 打通前端与原生的桥梁:JavaScriptCore 能干哪些事情?
40 | React Native、Flutter 等,这些跨端方案怎么选?
41 | 原生布局转到前端布局,开发思路有哪些转变?
42 | iOS原生、大前端和Flutter分别是怎么渲染的?
43 | 剖析使 App 具有动态化和热更新能力的方案
用户故事 (1讲)
用户故事 | 我是如何学习这个专栏的?
结束语 (1讲)
结束语 | 慢几步,深几度
iOS开发高手课
登录|注册

14 | 临近 OOM,如何获取详细内存分配信息,分析内存问题?

戴铭 2019-04-11
你好,我是戴铭。今天我们来聊聊,临近 OOM,如何获取详细的内存分配信息,分析内存问题的话题。
OOM,是 Out of Memory 的缩写,指的是 App 占用的内存达到了 iOS 系统对单个 App 占用内存上限后,而被系统强杀掉的现象。这么说的话,OOM 其实也属于我们在第 12 篇文章“iOS 崩溃千奇百怪,如何全面监控?”中提到的应用“崩溃”中的一种,是由 iOS 的 Jetsam 机制导致的一种“另类”崩溃,并且日志无法通过信号捕捉到。
JetSam 机制,指的就是操作系统为了控制内存资源过度使用而采用的一种资源管控机制。
我们都知道,物理内存和 CPU 对于手机这样的便携设备来说,可谓稀缺资源。所以说,在 iOS 系统的虚拟内存管理中,内存压力的管控就是一项很重要的内容。
接下来,我就跟你介绍一下如何获取内存上限值,以及如何监控到 App 因为占用内存过大而被强杀的问题?

通过 JetsamEvent 日志计算内存限制值

想要了解不同机器在不同系统版本的情况下,对 App 的内存限制是怎样的,有一种方法就是查看手机中以 JetsamEvent 开头的系统日志(我们可以从设置 -> 隐私 -> 分析中看到这些日志)。
在这些系统日志中,查找崩溃原因时我们需要关注 per-process-limit 部分的 rpages。rpages 表示的是 ,App 占用的内存页数量;per-process-limit 表示的是,App 占用的内存超过了系统对单个 App 的内存限制。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《iOS开发高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(20)

  • 白开了杯水
    一直不知道内存分配最大值获取和怎么获取当前内存分配,看了文章豁然开朗,想问的是,老师这些知识都是通过分析源码得来的吗?
    2019-04-11
    7
  • 我唔知点死啊
    fishhook初学者提问:
    关于fishhook malloc_logger,在libmalloc中找到malloc_logger是一个结构体:
    typedef void(malloc_logger_t)(uint32_t type,
    uintptr_t arg1,
    uintptr_t arg2,
    uintptr_t arg3,
    uintptr_t result,
    uint32_t num_hot_frames_to_skip);

    fishhook malloc_logger没有任何作用,然后在_malloc_initialize方法里面,找到这句malloc_logger = __disk_stack_logging_log_stack;
    fishhhok __disk_stack_logging_log_stack同样不起作用,现在无从下手,请指教。

    我的fishhook方法如下:
    static void (*original_disk_stack_logging_log_stack)(uint32_t type_flags,
                                   uintptr_t zone_ptr,
                                   uintptr_t arg2,
                                   uintptr_t arg3,
                                   uintptr_t return_val,
                                      uint32_t num_hot_to_skip);
    void new_disk_stack_logging_log_stack(uint32_t type_flags,
                                   uintptr_t zone_ptr,
                                   uintptr_t arg2,
                                   uintptr_t arg3,
                                   uintptr_t return_val,
                                   uint32_t num_hot_to_skip) {
        NSLog(@"========== __disk_stack_logging_log_stack ==========");
    }

            struct rebinding malloc_logger_rebinding = { "__disk_stack_logging_log_stack", original_disk_stack_logging_log_stack, (void *)&original_disk_stack_logging_log_stack};
            rebind_symbols((struct rebinding[1]){malloc_logger_rebinding}, 1);
    2019-04-18
    1
    2
  • 徐秀滨
    老师,我没找到malloc_logger这个方法,没法hook,咋搞?
    2019-04-17
    2
  • drunkenMouse
    iOS通过堆栈管理所有的app进程,通过一个优先级最高的线程去监控系统内存的压力,还有一个快速对照表记录所有app的内存使用情况。如果内存有压力了,就按照优先级去释放优先级低还使用内存多的。

    所以app得内存阈值是没有固定大小的。我一直以为每个app可以使用的内存大小是固定的。。
    2019-04-14
    2
  • 鼠辈
    info.resident_size这个获取的内存和xcode上显示的内存是对不上的。不知道您怎么看这个问题?

    作者回复: 使用的字段不同,task_vm_info_data_t 还有个 phys_footprint 代表的实际使用的物理内存

    2019-04-11
    2
  • 无名
    我问这个问题的原因是看到SDWebImage 2.6版本的源码中释放内存缓存有两种方式:
    第一种:监听到内存不足时,释放所有内存缓存;
    第二种:当系统剩余内存小于12M时,释放内存缓存。

    刚开始版本是没有加第二种判断的。我的疑问是加上第二种判断有必要吗?如果有必要的话,那么就是,当系统只剩12M内存都还没有触发内存不足的通知。

    所以说这个内存不足通知是否在应用能给它分配的最大内存都全部使用完了才发出通知还是?
    如:当前app能使用的最大内存为2G,系统总共内存为4G。那是否说不管系统是否还剩余多少内存,只要app的内存达到2G就发出内存警告通知?还是说快到2G,如达到最大可用内存的百分之95以上就发出内存警告通知。有哪里可以看到这个值吗?
    2019-06-25
    1
  • Jaker
    接上面的问题,问一下老师,task_vm_info_data_t的phys_footprint 打印输出的内存值和xcode的显示内存还是不一致啊,这是怎么回事,望解惑,谢谢。
    2019-04-16
    1
  • Calabash_Boy
    老师好,读完后有几个问题不得其解:
    (1) 在相同的设备和系统版本下,每个App的内存限制是不一样的么?我查看了手机的jetsamEvent,在per-process-limit中发现一个rpages是196.
    (2) 在vm_pressure_monitor线程的检测下,发现某App有了内存压力(理解为即将达到内存限制),然后会给该App发通知,然后您又讲到了优先级机制,这就有疑惑了,当某个App有压力的时候,是强杀这个App呢还是根据优先级去强杀后台的App呢?
    (3) 在测试struct mach_task_basic_info info;这段代码的时候,编译会报错Definition of 'mach_task_basic_info' must be imported from module 'Darwin.Mach.task_info' before it is required,是我没有导入某个头文件么?
    2019-04-13
    1
    1
  • 一直不知道内存分配最大值获取和怎么获取当前内存分配,看了文章豁然开朗,想问的是,老师这些知识都是通过分析源码得来的吗?
    2019-04-11
    1
  • RichardJ
    小结里说到访问未分配内存、向只读内存进行写操作的问题,戴老师可以举些例子说明下这两种情况怎么排查原因吗?
    2019-08-20
  • 夜空繁星
    除了膜拜,没别的。
    2019-07-16
  • 无名
    当系统还剩多少内存时,会发出内存不足的通知。

    作者回复: 本文都是围绕这个问题在说呢。会根据系统和硬件不同而定

    2019-06-25
  • 亡命之徒
    线上使用这种方式监控内存,苹果审核会通过嘛
    2019-06-25
  • mersa
    怎么知道谁调用了 malloc,来指导对应的堆栈信息
    2019-06-02
  • 二木又土
    JetsamEvent文件中搜索rpages,为什么有很多值,不同app能使用的最大内存大小是不一样的?
    2019-04-25
  • drunkenMouse
    系统在强杀App前,会先做优先级判断。意思是:如果优先级高的话,本来会强杀的也不强杀了,而去强杀那些没有达到limit的进程?

    作者回复: 强杀前系统会根据文后的策略判断应该优先强杀谁

    2019-04-13
  • drunkenMouse
    didReceivedMemory 动态获取内存值的方法,没有找到啊 大佬能说一下吗?

    作者回复: 是在 didReceiveMemoryWarning 回调里去获取当前 App内存使用值

    2019-04-13
  • drunkenMouse
    线程使用优先级时,CPU 占用多的线程的优先级会被降低。这句话怎么读不懂呢?

    利用didReceivedMemoryWarning 这个代理时间,看得我一愣。。应该是代理事件,我这算不算鸡蛋里面挑骨头?

    task_infk的使用需要导入<mach/mach.h>

    最后一段意思是,系统通过malloc_logger来统计并管理内存的分配情况?

    作者回复: 在你设置相同优先级的线程中,系统会有更细的优先级策略,这个策略就是哪个线程 CPU 占用高,优先级会比降低

    2019-04-12
  • Hy
    👌
    2019-04-12
  • mαnajay
    hook malloc_logger aop收集日志,然后在OOM那6秒内收集所有内存分配信息,然后在再次启动应用时 上报这两部分日志吗?
    oom那一刻是指的哪个时机,接受内存警告? didReceiveMemoryWarning 中判断 是否靠近 limit吗

    作者回复: OOM 是内存超标被系统强杀时

    2019-04-11
收起评论
20
返回
顶部