Memory Management di Wasm — WebAssembly

Memory Management di WebAssembly WebAssembly menggunakan linear memory — satu blok kontinu dari bytes yang bisa diakses dari Wasm dan JavaScript. Tidak ada garb

Memory Management di WebAssembly

WebAssembly menggunakan linear memory — satu blok kontinu dari bytes yang bisa diakses dari Wasm dan JavaScript. Tidak ada garbage collector, tidak ada object reference — hanya raw bytes.

Linear Memory

;; Deklarasi memory: initial 1 page, max 10 pages
;; 1 page = 64KB
(module
  (memory 1 10)  ;; start 64KB, max 640KB
  (export "memory" (memory 0))

  ;; Tulis angka ke memory offset 0
  (func $write (export "write")
    i32.const 0      ;; alamat (offset)
    i32.const 42     ;; nilai
    i32.store        ;; simpan 4 bytes di offset 0
  )

  ;; Baca angka dari memory offset 0
  (func $read (export "read") (result i32)
    i32.const 0      ;; alamat (offset)
    i32.load         ;; baca 4 bytes dari offset 0
  )
)

Memory.grow

// Wasm memory bisa di-grow (tapi tidak di-shrink)
const memory = new WebAssembly.Memory({
  initial: 1,   // 1 page = 64KB
  maximum: 100,  // max 100 pages = 6.4MB
});

console.log(memory.buffer.byteLength); // 65536

memory.grow(2); // tambah 2 pages (128KB)
console.log(memory.buffer.byteLength); // 196608

// ⚠️ PENTING: setelah grow, buffer reference berubah!
// Selalu re-read memory.buffer setelah grow
let view = new Uint8Array(memory.buffer); // harus re-create

Typed Arrays sebagai View

// Berbagai "lensa" untuk melihat memory yang sama
const buffer = instance.exports.memory.buffer;

const bytes   = new Uint8Array(buffer);     // per byte
const ints    = new Int32Array(buffer);      // per 4 bytes (int)
const floats  = new Float64Array(buffer);    // per 8 bytes (double)

// Tulis integer di offset 0
ints[0] = 1000;

// Baca byte individual dari integer yang sama
console.log(bytes[0]); // 232 (low byte of 1000)
console.log(bytes[1]); // 3   (high byte of 1000)

// Transfer array besar ke Wasm
const data = new Float64Array([1.1, 2.2, 3.3, 4.4]);
const wasmFloats = new Float64Array(buffer, 0, data.length);
wasmFloats.set(data); // copy ke Wasm memory

Allocator Pattern

Untuk bahasa tanpa runtime (Rust, C), kamu perlu allocator untuk dynamic memory:

// Rust dengan wee_alloc (allocator kecil untuk Wasm)
// Cargo.toml: wee_alloc = "0.4"

#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// Sekarang Vec, String, Box, dll. bisa digunakan

Common Pitfalls

Yang akan kamu pelajari