Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions guest_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ func guestEntry() {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// runGuest has released its state graph and input mapping. Collect after
// those roots leave the stack, before the guest process exits.
runtime.GC()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guestEntry replaces main.main, so once it returns the guest process exits and the OS reclaims the entire address space regardless of GC state. A synchronous runtime.GC() here does a full stop-the-world mark/sweep whose only product is freed heap that is about to be discarded anyway — it adds teardown latency on every Run without an observable benefit.

The deterministic cleanup this seems aimed at is already handled inside runGuest: defer unix.Close(3) and the deferred unmap() (munmap) run during runGuest's return, before control reaches this line. I confirmed there are no runtime.SetFinalizer registrations in the production state/reflectx packages, so GC won't trigger any observable finalizer cleanup either.

The comment is also slightly inaccurate: runGuest doesn't explicitly "release its state graph" — the graph is a stack local that simply becomes unreachable on return; only the input mapping is explicitly released (via unmap()).

Suggestion: remove the runtime.GC() call, or — if it's retained for a specific measured reason (e.g., heap-profile hygiene for tooling) — document that concrete reason and consider gating it so it doesn't run on the hot path.

}

func runGuest() (err error) {
Expand Down
Loading