Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

node has memory leak #4524

Closed
ningchunlei opened this issue Jan 6, 2013 · 11 comments
Closed

node has memory leak #4524

ningchunlei opened this issue Jan 6, 2013 · 11 comments

Comments

@ningchunlei
Copy link

server.js

var net=require("net")

var server = net.createServer(function (socket) {
socket.on("error",function(e){
console.log(e)
})
});

server.listen(7888,function() {
address = server.address();
console.log("opened server on %j", address);
});

client.js

var net=require("net")
max=100000
client=net.createConnection(7888,function(){
console.log("con")
buf = new Buffer(16*1024).toString();
for(i=0;i<max;i++){
b = client.write(buf)
}
console.log("end"+error)

})

so.memory grow bigger and bigger , but i run node --trace-gc client.js ,i found heap only 50m, but i top -p pid , rss is 1.3g, so what is the problem? there is some memory leak,

@indutny
Copy link
Member

indutny commented Jan 6, 2013

Apparently, you're not closing incoming connections which results in a leak. Also, buffers are allocated outside v8's heap, that's why you can't see real RSS when running node with --trace-gc.

Closing this issue.

@indutny indutny closed this as completed Jan 6, 2013
@ningchunlei
Copy link
Author

idont think so, if client.js
var net=require("net")
max=100000
client=net.createConnection(7888,function(){
console.log("con")
buf = new Buffer(16*1024) // before .toString();
for(i=0;i<max;i++){
b = client.write(buf)
}
console.log("end"+error)

})

just buf = new Buffer(16_1024) .toString() change to buf = new Buffer(16_1024), memory is few

and i cant understand you say you're not closing incoming connections which results in a leak,

var net=require("net")
max=100000
client=net.createConnection(7888,function(){
console.log("con")
buf = new Buffer(16*1024) // before .toString();
for(i=0;i<max;i++){
b = client.write(buf)
}
console.log("end"+error)
client.end()
})

i add client.end() . just the same and i want keep connection,dont close it . i think where is some malloc in node ,and dont free.

buf = new Buffer(16_1024) vs buf = new Buffer(16_1024) .toString()

there is different in src/stream_wap.cc:346

buf = new Buffer(16*1024) .toString() to malloc big memory,but in AfterWrite memthod delete[] it

so i dont undstand,, can you help me

@indutny indutny reopened this Jan 6, 2013
@indutny
Copy link
Member

indutny commented Jan 6, 2013

What node version are you using?

@ningchunlei
Copy link
Author

node-v0.8.16-linux-x64 ,
LSB Version: :core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 6.2 (Final)
Release: 6.2
Codename: Final

@indutny
Copy link
Member

indutny commented Jan 6, 2013

Ok, so what process is leaking: server or client?

@ningchunlei
Copy link
Author

client

@indutny
Copy link
Member

indutny commented Jan 6, 2013

socket.write() is asynchrononus function - it won't write any data until next tick will happen, so, in you case, writing so much data in a loop will result in temporary storing in memory:

(16 * 1024) * 100000 = 1638400000 bytes = 1600000 kb = 1562 mb = 1.52 gb.

Try writing less data, or writing it in parts.

@indutny indutny closed this as completed Jan 6, 2013
@ningchunlei
Copy link
Author

var net=require("net")
max=100000
count=0
client=net.createConnection(7888,function(){
console.log("con")
buf = new Buffer(16*1024).toString()
for(i=0;i<max;i++){
b = client.write(buf,function(){
count++;
if(count==max){
console.log("end")
client.end()
}
})
}
})

setTimeout(function(){
console.log(1)
},100000)

i add client.write(buf,function(){
count++;
if(count==max){
console.log("end")
client.end()
}
})

so the temporary storing in memory i found in src/stream_wap.cc:346

char * storage = new char[sizeof(WriteWrap)+storgize+15] this is temporary

but in src/stream_wap.cc:463

MakeCallback(); --> client.write(buf,function(){
count++;
if(count==max){
console.log("end")
client.end()
}
})
req_wrap->~WriteWrap();
delete[] reinterpret_cast<char*>(req_wrap)

so temporary shoud free,. but it cant ,

when i say console.log("end") , i say rss still 1.3g
so how to explain

@indutny
Copy link
Member

indutny commented Jan 6, 2013

you are still writing it all at once. try writing next chunk in socket.write()'s callback.

@ningchunlei
Copy link
Author

var net=require("net")
max=100000
count=0
buf = new Buffer(16*1024).toString()
client=net.createConnection(7888,function(){
write()
})

function write(){
client.write(buf,function(){
count++
if(count==max){
console.log("e")
return;
}
write()
})

}

setTimeout(function(){
console.log(1)
},1000000000)

yes , this is ok ,but why ? where is the temporary memory , can you tell me .

@indutny
Copy link
Member

indutny commented Jan 6, 2013

Imagine you're on a postal office and giving heavy letters to the worker. He'll stay and keep all your letters until he'll be able to go to the storage.

If you'll give him all letters at once, he'll hold very big amount of data (1.5 gb). But if you'll wait for him to come to the storage and return back to you, before giving him the next letter - worker won't need to hold everything at once and will use much less data.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants