記憶體峰值倍率: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,分頁直接被砍——攔不到就只能事前擋

相關:Worker 與分頁共用同一份記憶體配額WASM linear memory 是 GC 管不到的記憶體