{"record":{"id":"224b40a6b517ea83","repo":"dotnet/runtime","slug":"out-of-memory","errorCode":null,"errorMessage":"Out of memory","messagePattern":"Out of memory","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/mono/browser/runtime/memory.ts","lineNumber":343,"sourceCode":"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 {\n    const sp = Module.stackSave();\n    const ptr = Module.stackAlloc(bytesWanted);\n    try {\n        return f(ptr, ud1, ud2, ud3);\n    } finally {\n        if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp);\n\n    }\n}\n\n// @bytes must be a typed array. space is allocated for it in the native heap\n//  and it is copied to that location. returns the address of the allocation.\nexport function mono_wasm_load_bytes_into_heap (bytes: Uint8Array): VoidPtr {\n    // pad sizes by 16 bytes for simd\n    const memoryOffset = malloc(bytes.length + 16);\n    if (<any>memoryOffset <= 0) {\n        mono_log_error(`malloc failed to allocate ${(bytes.length + 16)} bytes.`);\n        throw new Error(\"Out of memory\");\n    }\n    const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);\n    heapBytes.set(bytes);\n    return memoryOffset;\n}\n\n// @bytes must be a typed array. space is allocated for it in memory\n//  and it is copied to that location. returns the address of the data.\n// the result pointer *cannot* be freed because malloc is bypassed for speed.\nexport function mono_wasm_load_bytes_into_heap_persistent (bytes: Uint8Array): VoidPtr {\n    // pad sizes by 16 bytes for simd\n    const desiredSize = bytes.length + 16;\n    // sbrk doesn't allocate whole pages so we can ask it for as many bytes as we want.\n    let memoryOffset = Module._sbrk(desiredSize);\n    if (<any>memoryOffset <= 0) {\n        // sbrk failed. Due to identical bugs in v8 and spidermonkey, this isn't guaranteed to be OOM.\n        // We use this function early during startup, when OOM shouldn't be possible anyway!\n        // Log a warning, then retry.","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/memory.ts#L325-L361","documentation":"mono_wasm_load_bytes_into_heap (and the persistent variant) allocates room for a byte buffer via Module._malloc / Module._sbrk; when the allocator returns <= 0 the wasm linear memory is exhausted and the runtime throws 'Out of memory'. The persistent variant retries sbrk once before failing.","triggerScenarios":"Loading a large Uint8Array into the heap (mono_wasm_load_bytes_into_heap) when the wasm linear memory has reached MAXIMUM_MEMORY and cannot grow further; or persistent sbrk failing twice during early startup allocation.","commonSituations":"Streaming large payloads/files through interop; the heap already near EmccMaximumHeapSize; processing big binary assets; a memory leak growing the heap to the cap.","solutions":["Increase EmccMaximumHeapSize (within the host's limit) so the heap can grow.","Reduce the size of the buffer being loaded; chunk large payloads and free intermediate buffers.","Free unmanaged allocations (free()) and release GCHandles/Span views to bring heap usage down.","If during startup, also check EmccInitialHeapSize is large enough for early allocations."],"exampleFix":"// before\nconst ptr = mono_wasm_load_bytes_into_heap(hugeBytes); // throws when heap full\n// after\n// publish with a larger cap and chunk the payload\ndotnet publish -p:EmccMaximumHeapSize=2147483648\n// and in JS: process in smaller slices, freeing each","handlingStrategy":"try-catch","validationCode":"// Estimate available heap headroom before a large copy.\nconst bytesNeeded = bytes.length + 16;\n// Module.HEAP8.byteLength vs MAXIMUM_MEMORY; this is a heuristic only.\nif (Module.HEAP8 && (Module.HEAP8.buffer.byteLength + bytesNeeded) > maxMemoryBytes) {\n  throw new Error('Likely out of memory: requested bytes would exceed the configured MAXIMUM_MEMORY.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const ptr = mono_wasm_load_bytes_into_heap(bytes);\n} catch (e) {\n  if (String(e?.message) === 'Out of memory') {\n    // free unused buffers / chunk the payload and retry each chunk\n  }\n  throw e;\n}","preventionTips":["Publish with a MAXIMUM_MEMORY large enough for peak heap use (within device limits).","Chunk large byte payloads and free intermediate allocations.","Release GCHandles/Span views and call free() on unmanaged buffers promptly.","Monitor heap growth to catch leaks before they exhaust the cap."],"tags":["memory","wasm","allocation","oom"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}