-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sending large amount of data to ServerResponse causes RSS and External memory leak #30902
Comments
Seems very similar to this issue even though it’s closed |
I did a bit more investigation and apparently the issue is caused by allocating In this particular case buffers are allocated a lot, V8 allocates them on external memory, frees the memory after Buffer is not used anymore but GC does not de-allocate the issue. So external memory is actually free just not de-allocated. As a workaround to force memory de-allocation we can call |
@andrewnester there is a chance that this issue may be related with glibc memory fragmentation? See #8871 and #33790 |
@puzpuzpuz #33790 doesn't look like relevant but #8871 might be but I don't know how to prove if it's relevant for us or not |
@andrewnester both of these issues are related with glibc memory fragmentation. To diagnose your issue you could try to switch to jemalloc (see #8871 (comment) for more details) and if that fixes your issue, it's most likely has something to do with memory fragmentation. |
pls evaluate the discussion in #31641 too - in that case, there is no |
@andrewnester Using your script I can't reproduce this on v14.18.1 or v16.13.0. On both OSX and Ubuntu the external memory stays stable. |
OP didn't follow up, @rudolf wasn't able to reproduce, and there's been no movement since late 2021 so I'll go ahead and close this out. |
http_outgoing.js
stream_writable.js
Hello!
When sending lots of data to response( for example downloading big files) using Buffer there is significant increase in RSS and External memory usage.
As you can see in my example I stop to send data when stream is paused and continue after
resume
call so it shouldn’t be buffered in response stream.Even though resume/pause called properly RSS/external memory is growing. Heap seems more or less stable.
Here are results of the calls to
process.memoryUsage
after starting downloading.Debugging using Chrome inspector made me suspect flow which is below.
When we try to write lots of data to response the response connection will be corked and uncorked on next tick here
https://github.com/nodejs/node/blob/v8.x/lib/_http_outgoing.js#L652
write_
method will return false to initiate backpressure andpause
will be called:https://github.com/nodejs/node/blob/v8.x/lib/internal/streams/legacy.js#L17
On the next tick connection will be uncorked and
clearBuffer
will be calledhttps://github.com/nodejs/node/blob/v8.x/lib/_stream_writable.js#L312
It results in calling
doWrite
herehttps://github.com/nodejs/node/blob/v8.x/lib/_stream_writable.js#L500
Then
stream._writev
will be called and result of this call will be ignoredhttps://github.com/nodejs/node/blob/v8.x/lib/_stream_writable.js#L394
Then as a result
afterWrite
will be called which causes emitting ofdrain
event and resuming stream even though we don't know if data on Step 5 was buffered or not.https://github.com/nodejs/node/blob/v8.x/lib/_stream_writable.js#L461
https://github.com/nodejs/node/blob/v8.x/lib/_stream_writable.js#L473
My suspect is that memory leaking happens on Step 5 but unfortunately I am not sure as I can't get V8 memory profile to see what is leaking in RSS/External memory.
Below is simple Node JS code which emulates downloading of large file with chunk of 1MBs sent to stream using Buffer as data.
The text was updated successfully, but these errors were encountered: