記憶體峰值倍率:OOM 發生在轉換的瞬間
峰值倍率 = 那條路上同一瞬間最多同時存在幾份完整資料,以穩定狀態大小 S 為單位。評估記憶體風險時,這個數字比常駐重要。
為什麼
OOM 不是發生在穩定狀態。常駐 460MB 聽起來安全,但如果載入的瞬間需要 920MB,裝置就得撐得住 920MB——撐不住就在那一秒掛掉,連「常駐只有 460MB」的機會都沒有。
峰值怎麼來的
以「把 bytes 載進一個 WASM 函式庫」為例:
ArrayBuffer S ──┐
├── 複製期間兩份並存 → 峰值 2S
WASM heap S ──┘
↓ GC 跑過(時機不由你決定)
WASM heap S關鍵在那一步是複製不是搬移:複製進行到一半時來源必須完整有效,所以兩份必然並存。複製完成後來源才變成垃圾,而大 buffer 通常直接進 V8 的 large object space,要等 major GC 才處理——所以 = null 之後數字不會立刻降。
匯出方向更糟:來源本來就在(它是資料來源),匯出產生第二份完整副本,壓縮再產生輸出,峰值最高的一刻往往落在使用者按下送出之後——最不能失敗的時間點。
倍率是相對值
資料變大它等比變大:460MB 的資料峰值 920MB,1GB 的資料峰值 2GB。所以拿定址上限反推可承載量時要先除以峰值倍率。
檢查清單
- 有沒有在載入前擋掉過大的輸入(大小門檻 + 看得懂的錯誤訊息)?
- 入口的檔案大小限制無法推導展開後的記憶體用量,兩個數字沒有關聯
- OOM 在 iOS 上不會給你 error event,分頁直接被砍——攔不到就只能事前擋