Skip to content

wasm: linear memory declared at 3.3GB, where the same program built with Go declares 29MB #5599

Closed as not planned

Description

@0pcom

TinyGo 0.41.1, -target wasm, browser.

A wasm module I build declares 3328 MB of linear memory. The same source built with standard Go declares 29 MB — a factor of 115. Reading memory.buffer.byteLength immediately after instantiateStreaming, before go.run, already reports 3328 MB, so this is declared rather than grown, and no Go code has run to allocate it.

It matters beyond the footprint: at 3.3GB, ordinary addresses sit above 2GB, which puts every syscall/js call into #5095 (addresses arriving as signed i32). The terminals in my program stay blank while everything around them draws, one uncaught RangeError per call.

What it is not

  • Not the collector. -gc=precise produces byte-identically 3328 MB. Consistent with the memory never having been allocated by the GC.
  • Not -stack-size. I pass -stack-size 1MB; on a small binary that accounts for about 6MB (2MB without it, 8MB with).
  • Not any one dependency. Built individually as package main importing only that package, with the same flags:
import declared
charmbracelet/glamour (pulls goldmark, chroma) 11 MB
gdamore/tcell/v2 1 MB
rivo/tview 1 MB
gdamore/proxima5 2 MB
xterm-go (a VT emulator) 1 MB
two smaller DOM packages 0 MB
all of them, in one program 3328 MB

So it appears to be emergent from the combination rather than attributable to a package, which is why I have not been able to reduce it further. Happy to bisect against a hypothesis if there is one worth testing — each build takes about 17 minutes, so I would rather aim than sweep.

Measuring it

// in wasm_exec.js constructor
globalThis.__memlog = () => this._inst.exports.memory.buffer.byteLength;

then, after instantiation:

(globalThis.__memlog() / 1048576).toFixed(0) + " MB"   // 3328 MB

Flags: -no-debug -stack-size 1MB -interp-timeout 10m. The stack size is needed because the default overflows in regexp/syntax.Simplify when expanding a bounded repeat ({1,256} in goldmark's linkify pattern) — the overflow does not fault, it corrupts, and regexp then panics at startup on a case it treats as unreachable. The interp timeout is needed because the default three minutes is not enough for goldmark.

Activity

  1. jakebailey commented on Sep 27, 2026

    @jakebailey
    Member

    @0pcom I couldn’t reproduce the 3.3GB initial memory size with glamour, tcell, and tview together, but I think the measurement might be misleading. this._inst is set inside go.run, which runs _start synchronously before returning. Not awaiting it doesn’t mean no Go code has run.

    Could you check instance.exports.memory.buffer.byteLength directly before calling go.run? Or share the .wasm so we can check its declared memory size?

    Also worth trying current dev. #5575 fixed false GC retention from globals, including with -gc=precise, after 0.42.0. I could reproduce excessive growth with a separate allocation test on 0.41.1, but not current dev.

  2. 0pcom commented on Oct 14, 2026

    @0pcom
    ContributorAuthor

    You are right about the measurement. this._inst is only set inside go.run, so my snippet could not have read the size before Go code ran, and the 3328 MB was grown rather than declared.

    I can't share that .wasm or rebuild it, because the program has since been reworked and no longer imports glamour, tview or proxima5. Reading the memory section of a larger module instead, skywire built with 0.44.0-dev (an 89 MB .wasm), declares 409 pages, which is 25.6 MiB. So I have nothing that shows a large declared size on current dev. I'm closing this, and I'll reopen with a module if I see it again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    wasmWebAssembly

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions