Giggle iOS · 内存分析

全课程逐课内存覆盖报告

iPhone 15 Pro 模拟器上以 idb 自动驱动,对 Pre-A1 口语积累各 Level 的课程逐节「进入 → 驻留 → 退出」采样物理内存足迹(phys_footprint),配合 leaks / vmmap region diff 归因内存增长来源。本页汇总 Lv1–Lv5 的定量轨迹与全程定性结论。

环境 iPhone 15 Pro sim · iOS 17.2 · Debug v1.34 (1199) 账号 QA / 游客态 方法 footprint · heap · leaks+memgraph · vmmap 采集期 2026-07-17 ~ 07-20
启动稳态足迹
814MB
扣除 66MB stack-logging 实测 ≈750
Lv5 终态
1576MB
单进程累积 L3→L5 全
累积峰值 (全程)
1597MB
未触 OOM,进程存活
逐课覆盖
219课次
L3·16 + L4·16 + L5·18 单元 全
真泄漏 (unreachable)
~31
全程可忽略 · 5–9KB
代码级泄漏累积
976
随课程数线性增长 · 136KB

01逐课内存轨迹

同一进程连续跑完 L3→L4→L5,每节课退出后回主页取足迹。曲线是平台震荡而非无界增长——GC 跟得上,高水位随新主题缓慢上抬。

phys_footprint 逐课走势(退出回主页值)

横轴=课程进出序号,纵轴=物理内存足迹 (MB)。背景色带区分 Level。悬停查看单课。

Lv3 建构词汇(天气/清洁/空中/海洋/厨房) Lv4 谈论世界(野生动物/昆虫/职业/社区/电器) Lv5 完整句子(烹饪/客厅/爬行/海上/乐器/建筑) 净增量 ≥40MB 的课(红点=拉高内存的课)

02哪节课拉高了内存?

单课「净增量」=该课退出后足迹 − 进入前足迹(这节课自己加载、缓存留下的净驻留)。答案集中在三类。

单课净增量 Top 12

按 after − before 排序(仅成功进入的课)。红=冷启动/新 Level 首批,橙=重型复习,蓝=普通内容课。

按课型的平均净增量

同一课型 47–101 节的平均值——规律高度一致。

拉高内存的三类课

① 进入新 Level 的冷启动首批课:Lv3 首课「天气2 +132 / 天气3 +142」「记忆游戏 +114」——新主题图集/音频冷加载。
② 所有「单元复习」重型游戏:平均 +12MB、68% 为正、最高 +61(选道具赛车/潜水类,资源最重)。
③ 天气类雨天动画是 Lv3 平台抬升主因。
反之 记忆游戏平均 ≈0(命中缓存后近零增量),普通内容课 +2.7。

03结论速览

五条主结论,按处置优先级排序。

尽快修复两个代码级泄漏随课程数线性累积

每进出一节课约漏 1 个未 invalidate 的 NSURLSession1.5–2sendWhenWebGLReady block 循环引用。leaks 从启动 25 处一路涨到 90+ 课后的 976 处(136KB),NSURLSession 相关 88、WebGL block 100。字节虽小,但连带 delegate/socket,长会话线性累积。

长会话关注连刷多 Level 不失控,但高水位缓慢上抬

Lv1 ~1050 → Lv2 ~1250 → Lv3 陡升 1387(天气动画重)→ Lv4-5 平台 ~1330-1560,累积峰值 1580MB。始终未触 OOM/jetsam、进程存活,GC 回收正常(模拟器 Debug 口径,真机内存更紧)。

高水位化主增长在 Unity 自管堆

untagged VM_ALLOCATE 从 553 涨到 1032MB / 3344 region;16MB IL2CPP GC section 饱和(26 个)后增长转为 16K 小 region 累积;malloc 侧也蠕动(MALLOC_SMALL→113MB、NANO→45MB)。Xcode 工具归因到此为界,再往里需 Unity Profiler / vmlite

健康无真泄漏,弹窗/H5 反复进出无逐次泄漏

unreachable 真泄漏全程 25→31 处 / 5–9KB,全是 Unity 分配器与 ObjC runtime 噪音。课程弹窗开关 ×10 一次性 +51MB 后完全持平;H5 课进出 ×7 减速震荡有 GC 回落——增长是资产缓存高水位(abandoned),非泄漏。

功能缺陷A1 拼读级媒体课在游客·离线态卡死

Lv6-9 的「字母X之歌」等视频/WebGL 课内容需联网拉取,游客·QA 离线环境拉不到 → 永久停在加载页、无退出按钮、只能杀进程。描红/钉板类互动课正常。建议加载失败要有超时兜底 + 可退出错误态。

04分层数据

泄漏累积(跨全部 Level)

leaks 总数几乎与「累计进出课程数」成正比。

启动基线内存构成

大头是 Unity/IL2CPP 自管堆,malloc 各区仅 ~140MB。

05各 Level 概览

Pre-A1 口语积累 = Lv1–Lv5(主题课引擎,16–18 单元/级);A1 阅读准备 = Lv6–Lv9(拼读引擎,9 单元/级,Lv9 锁定)。

Level主题足迹平台单课最大增量覆盖状态
Lv1日常/颜色/五官/身体…~1050复习赛车 +104满量 46 课次全通
Lv2宠物/感官/家庭/蔬菜…~1250家庭3 +91 / 蔬菜绘本 +84满量 30 课次全通
Lv3天气/清洁/空中/海洋/厨房1090–1220天气2 +132(本轮最大)逐课 16 单元全通
Lv4野生动物/昆虫/职业/社区/电器1150–1216≤ +33(缓存复用高)逐课 16 单元全通
Lv5烹饪/客厅/爬行/海上/乐器/建筑/家园/鸟类1230–1600复习潜水/蛋糕 +49逐课 18 单元 全全通
Lv6-8拼读·字母(绘本/歌/描红/钉板)~1330-1440描红 +87采样(歌曲课卡死)部分
Lv9Reading Little Words锁定

06建议(按优先级)

  1. 修 NSURLSession 泄漏线性累积:grep URLSession(configuration: 创建点,补 finishTasksAndInvalidate() 或改共享 session。
  2. sendWhenWebGLReady block cycle线性累积:weak 捕获 / 派发后清队列,打破 -[UnityAppController sendWhenWebGLReadyWithGameObject:function:content:] 环。
  3. 课程退出主动瘦身:Unity 侧 lesson exit 调 Resources.UnloadUnusedAssets() + GC.Collect(),压低 GC section 高水位(连刷累积峰值已达 1580MB)。
  4. 媒体课加载兜底:字母歌/绘本视频·WebGL 课内容拉取失败时加超时 + 可退出错误态,杜绝无限 loading 卡死(游客/离线/弱网触发)。
  5. 上线内存埋点:进/出课程采样 phys_footprint,观察低内存真机(2GB RAM)连刷多级是否逼近 jetsam 线。
  6. 退出竞态simctl terminate 时 CFNetwork 线程经 Unity 分配器触发 __cxa_pure_virtual abort;终止路径先停网络回调再析构 Unity(或容忍,退出期影响小)。

数据源:full_coverage.csv(203 行逐课进出)+ sweep_log.csv(时间线)+ memgraph/vmmap 归因。轨迹图取每课退出回主页的 phys_footprint;Lv3 天气2 单课峰值以 before→after 计 +132。本报告为模拟器 Debug 口径,真机绝对值更低但相对规律一致。