Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.2k
Closed
Labels
httpIssues or PRs related to the http subsystem.Issues or PRs related to the http subsystem.memoryIssues and PRs related to the memory management or memory footprint.Issues and PRs related to the memory management or memory footprint.
Description
- Version:
v7.7.3 - Platform:
macOS/Linux - Subsystem:
net/http
I noticed that n socket connections obtained with the HTTP upgrade mechanism use a lot more memory than n socket connections obtained with a plain net server. Consider for example the following test.
net server
'use strict';constnet=require('net');constheaders=['HTTP/1.1 101 Switching Protocols','Connection: Upgrade','Upgrade: foo','',''].join('\r\n');letcount=0;consthandler=(socket)=>{socket.resume();socket.write(headers);if(++count===150000){gc();constrss=process.memoryUsage().rss;console.log(rss/1024/1024);}};constserver=net.createServer({allowHalfOpen: true});server.on('connection',handler);server.listen(3000,()=>console.log('listening on *:3000'));net client
'use strict';constnet=require('net');constheaders=['GET / HTTP/1.1','Connection: Upgrade','Upgrade: foo','Host: localhost:3000','',''].join('\r\n');leti=0;(functioncreateClient(){constsocket=net.connect({localAddress: `127.0.0.${i%100+1}`,port: 3000});socket.on('connect',()=>{socket.resume();socket.write(headers);if(++i===150000)return;createClient();});})();http server
'use strict';consthttp=require('http');constheaders=['HTTP/1.1 101 Switching Protocols','Connection: Upgrade','Upgrade: foo','',''].join('\r\n');letcount=0;consthandler=(req,socket,head)=>{socket.resume();socket.write(headers);if(++count===150000){gc();constrss=process.memoryUsage().rss;console.log(rss/1024/1024);}};constserver=http.createServer();server.setTimeout(0);server.on('upgrade',handler);server.listen(3000,()=>console.log('listening on *:3000'));http client
'use strict';consthttp=require('http');leti=0;(functioncreateClient(){constreq=http.get({localAddress: `127.0.0.${i%100+1}`,port: 3000,headers: {'Connection': 'Upgrade','Upgrade': 'foo'}});req.on('upgrade',(res,socket,head)=>{socket.resume();if(++i===150000)return;createClient();});})();The first (net) server uses ~295 MiB of memory while the second (http) ~525 MiB. Shouldn't they use more or less the same amount of memory?
It seems that, in part, the difference is caused by the additional event listeners. If I add
socket.removeAllListeners('drain');socket.removeAllListeners('error');socket.removeAllListeners('timeout');in the upgrade event handler, memory usage drops to ~420 MiB.
Metadata
Metadata
Assignees
Labels
httpIssues or PRs related to the http subsystem.Issues or PRs related to the http subsystem.memoryIssues and PRs related to the memory management or memory footprint.Issues and PRs related to the memory management or memory footprint.