Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.3k
http: fixes memory retention issue with FreeList and HTTPParser#33190
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
leidegre commented May 1, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Adding this for clarification. This isn't a strict memory leak issue. There's an upper limit to the free list of a 1000 entries, which means that at most, it will retain up to 1000 times whatever the amount of bytes retained by event handlers. In our case this was about 1.5 MB (our heap usage eventually grew to about 1.5 GB as the free list is filled up when the site is under heavier load, this takes several days to happen). This issue has resulted in production outages due to memory starvation and I'm very eager to get this fixed. |
nodejs-github-bot commented May 1, 2020 • edited by ronag
Loading Uh oh!
There was an error while loading. Please reload this page.
edited by ronag
Uh oh!
There was an error while loading. Please reload this page.
Trott left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker to landing this, but is it possible to add a test?
Trott commented May 2, 2020
@nodejs/http |
Trott commented May 2, 2020
@leidegre Thanks for all the work you did to track this down! |
leidegre commented May 2, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@Trott Thanks. I understand the desire to add a test but I'm not sure how I would go about that in a meaningful manner given the particulars of the code changes. It would be a lot of work for me to make a meaningful contribution. I would be happy to verify any commits/builds though. |
lpinca commented May 2, 2020
@leidegre it should be sufficient to verify that Anyway it can be added also in follow up PR. |
lpinca commented May 3, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@leidegre feel free to add the following test under 'use strict';constcommon=require('../common');constassert=require('assert');consthttp=require('http');const{ HTTPParser }=require('_http_common');// Test that the `HTTPParser` instance is cleaned up before being returned to// the pool to avoid memory retention issues.constkOnTimeout=HTTPParser.kOnTimeout|0;constserver=http.createServer();server.on('request',common.mustCall((request,response)=>{constparser=request.socket.parser;assert.strictEqual(typeofparser[kOnTimeout],'function');request.socket.on('close',common.mustCall(()=>{assert.strictEqual(parser[kOnTimeout],null);}));response.end();server.close();}));server.listen(common.mustCall(()=>{constrequest=http.get({port: server.address().port});letparser;request.on('socket',common.mustCall(()=>{parser=request.parser;assert.strictEqual(typeofparser.onIncoming,'function');}));request.on('response',common.mustCall((response)=>{response.resume();response.on('end',common.mustCall(()=>{assert.strictEqual(parser.onIncoming,null);}));}));})); |
d5cf198 to 85b3bd7Compareleidegre commented May 3, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@lpinca Thanks! I've included the test in the PR (I've amended this commit). I've also verified that the test fails with Node 14 and that it succeeds with these changes applied. The test is here test/parallel/test-http-parser-memory-retention.js. |
85b3bd7 to 5057d36Comparenodejs-github-bot commented May 3, 2020
nodejs-github-bot commented May 4, 2020
leidegre commented May 4, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
This is currently an issue with Node 12 (as well as 14) so I was wondering what the process is for landing this in 12 (given that it's the current LTS) and that 14 will become the next LTS? Do I need to do something for this to happen or will this be added to some list and integrated into the next release? |
leidegre commented May 4, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@addaleax Mind reader! 👍 |
addaleax commented May 4, 2020
Commits are backported to LTS by default, so unless there are merge conflicts, no. If there are merge conflicts, you will be pinged, though. Also, just so you know, as a rule commits have to be released for 2 weeks in a Current (i.e. 14.x) release before they are backported to LTS release lines. I’ve added the lts-watch label, but that’s more in order to make sure that this is taken into consideration and to explicitly mark this as something that should land on lts-v12.x.
I just saw your comment, that’s all 😄 |
leidegre commented May 5, 2020
Looks like some of the checks have failed with some transient Git issue? I don't know if I can do anything about it... |
nodejs-github-bot commented May 5, 2020
nodejs-github-bot commented May 5, 2020 • edited by ronag
Loading Uh oh!
There was an error while loading. Please reload this page.
edited by ronag
Uh oh!
There was an error while loading. Please reload this page.
leidegre commented May 5, 2020
Everything good now? |
Fixes: #29394 Refs: #33167 (comment) PR-URL: #33190 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]>
Flarna commented May 5, 2020
Landed in 26f1500 |
Fixes: #29394 Refs: #33167 (comment) PR-URL: #33190 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]>
codebytere commented Jun 7, 2020
Backport currently blocked on #32329. |
leidegre commented Jun 7, 2020
@codebytere This is important to me. Is there anything I can do to unblock this? |
codebytere commented Jun 7, 2020
Flarna commented Aug 18, 2020 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Fixes: #29394 Refs: #33167 (comment) PR-URL: #33190 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Gerhard Stöbich <[email protected]>
Fixes: #29394
Refs: #33167 (comment)
The issue here is that because the HTTPParser is pooled it has the possibility to act as a retainer of a lot of data. In summary we have to reset
parser.onIncomingandparser[kOnTimeout]tonullto prevent these from retaining memory while the HTTPParser is sitting in the FreeList unused.I'd like this to eventually be cherry picked into the Node 14 release.
See the reference for details.
@ronag Here's your PR.