dotnet/runtime · critical · Error

Out of memory

Error message

Out of memory

What it means

Thrown by mono_wasm_load_bytes_into_heap when the native malloc returns a non-positive pointer for the requested size (bytes.length + 16 bytes of SIMD padding). It signals the Wasm linear memory cannot satisfy the allocation, i.e. the managed/native heap is exhausted. The thrown Error is the user-visible form of an allocator failure during data marshaling into the native heap.

Solutions

  1. Reduce the size of the byte payload being loaded; chunk it into smaller allocations.
  2. Enable/grow the Wasm linear memory limit (Module.MAXIMUM_MEMORY / -s ALLOW_MEMORY_GROWTH) and confirm the runtime can grow memory.
  3. Audit for native heap leaks - ensure previously malloc'd buffers are freed with _free so subsequent allocations succeed.
  4. Stream the data instead of loading it whole into native heap.

Example fix

// before
const ptr = mono_wasm_load_bytes_into_heap(hugeBytes);
// after
const chunkSize = 1 << 20;
for (let i = 0; i < hugeBytes.length; i += chunkSize) {
  const chunk = hugeBytes.subarray(i, Math.min(i + chunkSize, hugeBytes.length));
  mono_wasm_load_bytes_into_heap(chunk);
}
Defensive patterns

Strategy: try-catch

Validate before calling

function canAllocateHeap(bytes: Uint8Array): boolean {
  // rough guard: total requested must be below half of currently free linear memory
  const free = Module.HEAP8.length; // proxy for current limit
  return bytes.length + 16 < free;
}

Try / catch

try {
  const ptr = mono_wasm_load_bytes_into_heap(bytes);
} catch (e) {
  if ((e as Error).message === 'Out of memory') {
    // reduce payload, grow memory, or report to user
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling mono_wasm_load_bytes_into_heap with a very large Uint8Array when the Wasm module's linear memory is near its maximum, or when many allocations have fragmented/consumed the heap. The malloc inside the runtime returned <= 0.

Common situations: Loading large assemblies, binaries, or media blobs into native memory; running under memory-constrained devices; not growing the Wasm memory (ALLOW_MEMORY_GROWTH off) with a large dataset; a leak in native heap usage keeping prior allocations alive.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/224b40a6b517ea83. Report an issue: GitHub.

Appendix: source

Thrown at src/mono/browser/runtime/memory.ts:343

export function withStackAlloc<T1, T2, T3, TResult> (bytesWanted: number, f: (ptr: VoidPtr, ud1?: T1, ud2?: T2, ud3?: T3) => TResult, ud1?: T1, ud2?: T2, ud3?: T3): TResult {
    const sp = Module.stackSave();
    const ptr = Module.stackAlloc(bytesWanted);
    try {
        return f(ptr, ud1, ud2, ud3);
    } finally {
        if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp);

    }
}

// @bytes must be a typed array. space is allocated for it in the native heap
//  and it is copied to that location. returns the address of the allocation.
export function mono_wasm_load_bytes_into_heap (bytes: Uint8Array): VoidPtr {
    // pad sizes by 16 bytes for simd
    const memoryOffset = malloc(bytes.length + 16);
    if (<any>memoryOffset <= 0) {
        mono_log_error(`malloc failed to allocate ${(bytes.length + 16)} bytes.`);
        throw new Error("Out of memory");
    }
    const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);
    heapBytes.set(bytes);
    return memoryOffset;
}

// @bytes must be a typed array. space is allocated for it in memory
//  and it is copied to that location. returns the address of the data.
// the result pointer *cannot* be freed because malloc is bypassed for speed.
export function mono_wasm_load_bytes_into_heap_persistent (bytes: Uint8Array): VoidPtr {
    // pad sizes by 16 bytes for simd
    const desiredSize = bytes.length + 16;
    // sbrk doesn't allocate whole pages so we can ask it for as many bytes as we want.
    let memoryOffset = Module._sbrk(desiredSize);
    if (<any>memoryOffset <= 0) {
        // sbrk failed. Due to identical bugs in v8 and spidermonkey, this isn't guaranteed to be OOM.
        // We use this function early during startup, when OOM shouldn't be possible anyway!
        // Log a warning, then retry.

View on GitHub (pinned to 60108ba66e)