NodeJS:如何释放在V8内存堆外部分配的缓冲区

我有一个应用程序,我从服务器上顺序下载MP3文件,暂时将它们存储在我的服务器中,然后直接将它们stream式传输到客户端,如下所示:

function downloadNextTrack(){ var request = http.get('http://mp3server.com', function(response){ response.on('data', function(data) { fs.appendFile('sometrack.mp3', data, function (err) {}); }); response.on('end', function(){ streamTrack('sometrack.mp3'); } }); }; var clients = []; // client response objects are pushed to this array when they request the stream through a route like /stream.mp3 var stream; function streamTrack(track){ stream = fs.createReadStream(track); stream.on('data', function(data){ clients.forEach(function(client) { client.write(data); }); }); stream.on('end', function(){ downloadNextTrack(); // redoes the same thing with another track } }; 

显然这段代码创build了很多不被操作系统释放的缓冲区,当我运行'free -M'命令时,这就是我得到的(大约运行了4个小时之后):

  total used free shared buffers cached Mem: 750 675 75 0 12 180 -/+ buffers/cache: 481 269 Swap: 255 112 143 

“缓冲区”下的数字不断上升(以及高速caching的内存),操作系统显然没有收回180MB的内存,直到最终我的应用程序内存不足,崩溃时,我尝试产生一个小的进程来validation轨道的比特率,采样率,id3信息等

我已经诊断了很多不同的工具(如memwatch和nodetime),以确定它是否是内部内存泄漏,而不是,V8内存堆以及Node RSS变化+/- 10mb,但保持不变在大多数情况下,操作系统的空闲内存越来越低(当节点进程启动时,我有大约350MB的空闲内存)。

我在某处读到Node分配的Buffer实例可以直接访问原始内存,所以V8没有对它们进行控制(这个事实certificate我没有从V8堆中获取内存泄漏),事实上,我需要一种方法来摆脱这些旧的缓冲区。 这可能吗? 或者我将不得不每5个小时左右重新启动我的应用程序(或更糟的是,购买更多的内存!)?

PS。 我在Ubuntu 10.04上运行Node v0.8.16。

我同意蒂亚戈,我认为这是由于你的代码的recursion性质造成的。 我不认为这些stream是吞噬你的堆的东西,因为正如你所说的那样,streamvariables在每次迭代中都被重新分配一个新的ReadStream。 然而,在调用下一个迭代之前,第二行中的http.get的请求和响应(以及他们使用的任何缓冲区)永远不会被释放。 它们的范围在downloadNextTrack函数中。 您最终得到一个recursion堆栈跟踪,每个文件都有一组请求和响应对象(以及一些底层缓冲区)。

一般来说,如果这段代码需要运行很多次,那么为什么不select退出并迭代执行呢? 一个永无止境的recursion总是会吞噬越来越多的内存,直到程序崩溃,即使你没有内存泄漏。

阅读: http : //www.linuxatemyram.com

缓冲区caching是inode和dentries(文件系统结构)的caching。 该内存仍可用于进程。 你不应该在乎这个。