iOS-OOM(out-of-memery)
Jetsam管理的一种crash机制,通过Signal无法捕捉到Jetsam,iOS不支持交换空间,无RAM和DISK之间的映射,这是因为移动端大多数设备均为闪存。
Jetsam crash日志
{"bug_type":"298","timestamp":"2020-10-19 11:27:59.22 +0800","os_version":"iPhone OS 14.0.1 (18A393)","incident_id":"48A5344C-34D3-4FD1-BAF3-EAFBC1F15842"}
{
"crashReporterKey" : "ed5786382fe57f1c8c847aa1995b4ae301ff1eea",
"kernel" : "Darwin Kernel Version 20.0.0: Fri Aug 28 23:07:00 PDT 2020; root:xnu-7195.0.46~9\/RELEASE_ARM64_T8020",
"product" : "iPhone11,6",
"incident" : "48A5344C-34D3-4FD1-BAF3-EAFBC1F15842",
"date" : "2020-10-19 11:27:59.22 +0800",
"build" : "iPhone OS 14.0.1 (18A393)",
"timeDelta" : 89,
"memoryStatus" : {
"compressorSize" : 66687,
"compressions" : 1574450,
"decompressions" : 920590,
"zoneMapCap" : 1441710080,
"largestZone" : "vm pages array",
"largestZoneSize" : 11223040,
"pageSize" : 16384,
"uncompressed" : 177283,
"zoneMapSize" : 127418368,
"memoryPages" : {
"active" : 54456,
"throttled" : 0,
"fileBacked" : 32811,
"wired" : 52390,
"anonymous" : 75798,
"purgeable" : 1361,
"inactive" : 53082,
"free" : 4344,
"speculative" : 1071
}
},
"largestProcess" : "XXXApp",
"genCounter" : 1,
"processes" : [
{
"uuid" : "213c33d7-a2a9-333e-b1e8-293fa1f3a4ce",
"states" : [
"daemon",
"idle"
],
"age" : 1406544508698,
"purgeable" : 0,
"fds" : 25,
"coalition" : 486,
"rpages" : 75,
"priority" : 0,
"physicalPages" : {
"internal" : [
1,
62
]
},
...
- rpages代表页的大小,
- pageSize" : 16384,为当前设备页框的大小4KB
- 通过 rpages * pageSize 就能得出当前app被杀掉时占用的内存
## Jetsam机制
它可以理解为操作系统为了控制内存资源过度使用而采用的一种管理机制。Jetsam是一个独立运行的进程,每一个进程都有一个内存阈值,超过这个值的时候,如果手机系统内存吃紧就很大几率被系统杀掉.
为什要设计Jetsam机制
大部分的移动设备都不支持交换空间(虚拟内存,将部分物理内存交换到磁盘空间上,利用硬盘来扩展内存空间),而移动端设备通常采用闪存存储,读写速度远小于电脑硬盘,就算使用了交换空间也不一定能够起到很好的效果,而且移动设备的容量本省比较小,所以不大适合拿山存来进行内存交换。
内存一般分为这个几个状态
Clean memory, 如frameworks中的__DATA_CONST
,如果有新的数据写入就编程dirty
Dirty memory, 被写入过数据的区域,如_DATA
和_DATA_DIRTY
段,他们是Dirty memory
Compressed Memory 压缩内存,用来替代交换机制,增加内存的利用率。 主要正对 不获取的内存压缩,支持多核操作
在计算内存时 压缩的内存也属于 Dirty memory
Memory Warning
内存警告,是系统的一种预警行为,如iOS中的didReceivedMemoryWarning
合理利用缓存能提升app的性能,但同时也要避免内存的过度开销,主意清理时机,设置适当的策略进行优化。 比如避按活跃度清理,按大小清理,懒加载,内存警告时清理不必要的缓存,设置时间策略,将果酒的缓存清理等等, 可以考虑使用NSCache代理NSDictionary,NSCache内部实现了一套机制可以在内存过高的时候帮助释放不常用的存储数据。
OOM的阈值
这个没有一个明确的值,这个和机型,设备当前的运行状态等诸多因数有关,根据我自己的XS的Jetsam的数据来看一般操作500M就有几率出现OOM了,内存占用越高越容易出现OOM
各机型MOO的参考值
Apple FootPrint
statckoverflow参考地址
device: (crash amount/total amount/percentage of total)
iPad1: 127MB/256MB/49%
iPad2: 275MB/512MB/53%
iPad3: 645MB/1024MB/62%
iPad4: 585MB/1024MB/57% (iOS 8.1)
iPad Mini 1st Generation: 297MB/512MB/58%
iPad Mini retina: 696MB/1024MB/68% (iOS 7.1)
iPad Air: 697MB/1024MB/68%
iPad Air 2: 1383MB/2048MB/68% (iOS 10.2.1)
iPad Pro 9.7": 1395MB/1971MB/71% (iOS 10.0.2 (14A456))
iPad Pro 10.5”: 3057/4000/76% (iOS 11 beta4)
iPad Pro 12.9” (2015): 3058/3999/76% (iOS 11.2.1)
iPad Pro 12.9” (2017): 3057/3974/77% (iOS 11 beta4)
iPad Pro 11.0” (2018): 2858/3769/76% (iOS 12.1)
iPad Pro 12.9” (2018, 1TB): 4598/5650/81% (iOS 12.1)
iPad 10.2: 1844/2998/62% (iOS 13.2.3)
iPod touch 4th gen: 130MB/256MB/51% (iOS 6.1.1)
iPod touch 5th gen: 286MB/512MB/56% (iOS 7.0)
iPhone4: 325MB/512MB/63%
iPhone4s: 286MB/512MB/56%
iPhone5: 645MB/1024MB/62%
iPhone5s: 646MB/1024MB/63%
iPhone6: 645MB/1024MB/62% (iOS 8.x)
iPhone6+: 645MB/1024MB/62% (iOS 8.x)
iPhone6s: 1396MB/2048MB/68% (iOS 9.2)
iPhone6s+: 1392MB/2048MB/68% (iOS 10.2.1)
iPhoneSE: 1395MB/2048MB/69% (iOS 9.3)
iPhone7: 1395/2048MB/68% (iOS 10.2)
iPhone7+: 2040MB/3072MB/66% (iOS 10.2.1)
iPhone8: 1364/1990MB/70% (iOS 12.1)
iPhone X: 1392/2785/50% (iOS 11.2.1)
iPhone XS: 2040/3754/54% (iOS 12.1)
iPhone XS Max: 2039/3735/55% (iOS 12.1)
iPhone XR: 1792/2813/63% (iOS 12.1)
iPhone 11: 2068/3844/54% (iOS 13.1.3)
iPhone 11 Pro Max: 2067/3740/55% (iOS 13.2.3)
参考
1.https://github.com/Tencent/OOMDetector
2.https://www.taodudu.cc/news/show-5381.html
3.https://juejin.im/post/6885144933997494280