2015-04-19 132 views
0

我在Node.js上有服务器端的基于TCP的客户端/服务器应用程序。由于TCP是一个流,我需要单独的数据包,所以我会在每个数据包之前发送两个字节的长度(我猜是常见做法)。大数据包可能会进入少量块(因为MTU和其他东西),因此我需要从当前缓冲区中提取每个数据包,然后将剩下的数据包与下一个传入块进行连接并再次解析。我想出了下面的代码:切片缓冲区的垃圾回收

function parsePackets(data) { 
    // join existing buffer contents with new chunk 
    var buffer = Buffer.concat([this.buffer, data]); 

    var start = 0; 
    var end = buffer.length; 

    var packets = []; 

    while (true) { 
     // wait for at least two bytes 
     if (end - start < 2) { 
      break; 
     } 

     var length = buffer.readUInt16BE(start); 

     // wait until we can read whole packet 
     if (end - start < length) { 
      break; 
     } 

     // push packet data as a separate packet 
     //var data = new Buffer(length); 
     //buffer.copy(data, 0, start, start + length); 
     var data = buffer.slice(start, start + length); 
     packets.push(data); 

     start += length; 
    } 

    // drop parsed buffer contents, leaving the rest 
    //var newBuffer = new Buffer(buffer.length - start); 
    //buffer.copy(newBuffer, 0, start, buffer.length); 
    //this.buffer = newBuffer; 
    this.buffer = buffer.slice(start, buffer.length); 

    return packets; 
} 

我关心的是:将切掉缓冲区的内容被垃圾收集?我也在做concat返回新的缓冲区(我假设从提供的缓冲区复制内容,这意味着它们可以被垃圾收集)。或者,也许我需要使用copy而不是slice(我在注释行中有一个示例)?

我想没有内存泄漏高性能的代码,所以我不想比我要更复制数据。但目前看起来我的应用程序的内存使用量变得越来越大(我不知道如何测试它,以及如何检查切掉的内容是否会被释放)。

回答

1

有缓冲区对象的代码没有积累泄漏。

任何缓冲的对象,你不再保留在你的代码将立即可进行垃圾回收的参考。因此,在每次调用parsePackets()时,您创建.concat().slice()几个新的缓冲区对象,但只保留在this.buffer实例变量每个时间和缓冲更换为新的缓冲区每次(使一个缓冲对象的引用先前有资格进行垃圾收集)。

因此,有在该代码中没有堆积或缓冲对象的累积泄漏。


有关完整代码的整洁,你会想,以确保当你读完所有的数据,存储在this.buffer最后一个缓冲区对象的东西归零出像this.buffer = null;所以没有提及保留它即使处理完成。持有这个引用的对象本身并不需要清理。

+0

>完成读取所有数据。你什么意思?只要客户端连接,总是有数据需要读取。当客户端将断开这个。缓冲区将随着这个被破坏。 – bobby

+1

@bobby - 好的,那么这个部分很好。你没有展示整个对象的生命周期是如何管理的,所以我无法知道它是如何被使用的。 – jfriend00

1

在缓冲区,没有什么实际切掉。通过切片操作,会创建一个指向新位置的缓冲区的新视图,并具有自己的长度。修改原始缓冲区,也会修改切片缓冲区。 根据你的代码,你只会在Buffer.concat中创建一个新的缓冲区。之后,您将其几个块分配到数据包中并休息到this.buffer中。所有这些缓冲区都将指向通过concat方法创建的原始缓冲区。这是最有效的内存有效方法,除非2个块有重叠内存,否则不会产生任何问题。