Skip to content

Release the NB gc timer when an incoming socket closes - #70

Merged
vheun merged 1 commit into
mainfrom
valentinMS4
Aug 3, 2026
Merged

Release the NB gc timer when an incoming socket closes#70
vheun merged 1 commit into
mainfrom
valentinMS4

Conversation

@vheun

@vheun vheun commented Aug 3, 2026

Copy link
Copy Markdown

enhance() starts a 10s interval to time out stalled transfers and only unref()s it. unref keeps the timer from holding the process open, but the Timeout stays in Node's timer list - a GC root - so the interval's closure pinned nb, sched, opts and the socket itself, with all its eventCallbacks and the dead net.Socket. Every WebSocket a server ever accepted stayed in the heap.

Measured against a real ToolSocket server, incoming sockets that connect, subscribe and close: 19,035 B retained per connection at N=200 and 17,417 B at N=600 - linear in connection count. With the close handler: 1,862 B and 237 B, and the total falls from 372 KB to 142 KB between those runs, i.e. no longer proportional to N.

Guarded exactly like the pressure-registry entry above it: an auto-reconnecting outgoing socket keeps its timer across reconnects, while an incoming socket (url === null) can never reopen and releases it. large_object_space and external deltas were zero throughout - this is plain old-space retention.

enhance() starts a 10s interval to time out stalled transfers and only
unref()s it. unref keeps the timer from holding the process open, but
the Timeout stays in Node's timer list - a GC root - so the interval's
closure pinned nb, sched, opts and the socket itself, with all its
eventCallbacks and the dead net.Socket. Every WebSocket a server ever
accepted stayed in the heap.

Measured against a real ToolSocket server, incoming sockets that
connect, subscribe and close: 19,035 B retained per connection at
N=200 and 17,417 B at N=600 - linear in connection count. With the
close handler: 1,862 B and 237 B, and the total falls from 372 KB to
142 KB between those runs, i.e. no longer proportional to N.

Guarded exactly like the pressure-registry entry above it: an
auto-reconnecting outgoing socket keeps its timer across reconnects,
while an incoming socket (url === null) can never reopen and releases
it. large_object_space and external deltas were zero throughout - this
is plain old-space retention.
@vheun
vheun requested a review from hobinjk-dts August 3, 2026 21:05
@vheun
vheun merged commit c3f5fa9 into main Aug 3, 2026
6 checks passed
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.

2 participants