Skip to content

runtime: build tag to turn off the finalizer pressure GC - #5819

Open
joeblew999 wants to merge 1 commit into
tinygo-org:devfrom
joeblew999:runtime-finalizer-gc-tag
Open

joeblew999 wants to merge 1 commit into
tinygo-org:devfrom
joeblew999:runtime-finalizer-gc-tag

Conversation

@joeblew999

Copy link
Copy Markdown

Updates #5800.

The problem. The scheduler runs a full collection whenever it goes idle and finalizerGCThreshold finalizers were registered since the last one. A syscall/js program registers a finalizer for every js.Value and goes idle at every await, so it collects at nearly every pause. In a real program (an HTTP API on Cloudflare Workers) this was the largest single cost we measured: 38 to 71 ms of CPU per request with the trigger, 9 to 13 ms without, same heap.

The change. finalizerGCThreshold already means "off" when it is zero. This moves the constant into two files, as build_asserts.go / build_noasserts.go do for runtime_asserts, so that -tags=runtime_nofinalizerpressure selects zero. The default is unchanged: nothing differs for a program built without the tag.

Measured with the reproduction in #5800 (-target wasm, run with Node; each of 100 rounds makes 40 JS values and waits once for the event loop):

collections in 100 rounds
this branch, default 100
this branch, -tags=runtime_nofinalizerpressure 2

testdata/finalizer.go, finalizeridle.go, finalizerbits.go, finalizerinvariants.go and finalizerlarge.go, built for wasm without the tag and run with Node, give their expected output.

Open to a different shape. A tag is the smallest thing that lets a program opt out. If you would rather make the default cheaper for syscall/js programs (counting only finalizers whose objects could have died, or scaling with heap use), I am glad to rework this, and the tag name is yours to choose.

…r pressure GC

The scheduler runs a full collection whenever it goes idle and
finalizerGCThreshold finalizers were registered since the last one. A
syscall/js program registers a finalizer for every js.Value and goes idle at
every await, so it collects at nearly every pause: 100 collections in 100
event-loop turns in the reproduction in tinygo-org#5800.

The threshold already means 'off' when it is zero. This moves the constant
into two files so that -tags=runtime_nofinalizerpressure selects zero. The
default is unchanged.

Updates tinygo-org#5800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant