WASM linear memory 是 GC 管不到的記憶體

WASM heap(線性記憶體)就是一塊連續的 bytes,從 JS 看過去是一個巨大的 ArrayBuffer。C 程式碼裡的「位址 0x1000」在 JS 這邊就是 HEAPU8[0x1000]——指標其實只是這個 buffer 的索引

對照 JS heap

JS heapWASM heap
誰管V8 的 GC 自動回收C 程式碼自己 malloc / free
結構物件圖,有 header、hidden class一整塊連續 bytes
怎麼變小GC 跑過就回收只有 free() 會還,整塊配額通常不縮回去

WebAssembly.Memory 只有 grow() 沒有 shrink()——向瀏覽器要過的空間就不會還。庫內部 free 掉的空間會被它自己重複利用,但整塊不縮。

兩個實務後果

  1. 必須顯式關閉:JS 的 GC 只會回收那個指向 WASM memory 的包裝物件,碰不到裡面的資料。所以像 sql.js 這種函式庫,重新載入前一定要先 db.close(),否則每次都疊加一份完整資料,是穩定洩漏。
  2. devtools 的數字不會降:載入後記憶體居高不下是正常的,不代表洩漏。

硬上限

wasm32 的位址是 32-bit 整數,2^32 = 4GB——這是規格層級的天花板,不是瀏覽器政策(memory64 提案尚未普及)。實務上還會先撞到單一 ArrayBuffer 的上限(Chrome 約 2GB)與 Worker 與分頁共用同一份記憶體配額