【问题标题】:Node.js net tcp buffering memory leakNode.js net tcp 缓冲内存泄漏
【发布时间】:2015-06-10 07:14:25
【问题描述】:

我正在用 Node.js 编写一个 TCP 游戏服务器,但在将 TCP 流拆分为消息时遇到了问题。因为我想从缓冲区读取数字和浮点数,所以我找不到合适的模块来外包,因为我发现的所有模块都处理以换行符结尾的简单字符串。我决定用消息的字节长度为每条消息添加前缀。我这样做并编写了一个简单的程序,用随机消息向服务器发送垃圾邮件(构造良好,带有描述消息长度的 UInt16LE 前缀)。我注意到,我让程序运行我的实际服务器的时间越长,就会消耗越来越多的内存。我尝试使用调试工具来跟踪内存分配但没有成功,所以我想我会在这里发布我的代码并希望得到答复。所以这是我的代码......任何关于我哪里出错或我可以做不同/更有效的事情的提示或指针都会很棒! 谢谢。

server.on("connection", function(socket) {
var session = new sessionCS(socket);
console.log("Connection from " + session.address);

// data buffering variables
var currentBuffer = new Buffer(args.bufSize);
var bufWrite = 0;
var bufRead = 0;
var mSize = null;
var i = 0;

socket.on("data", function(dataBuffer) {

    // check if buffer risk of overflow
    if (bufWrite + dataBuffer.length > args.bufSize-1) {
        var newBufWrite = 0;
        var newBuffer = new Buffer(args.bufSize);

        while(bufRead < bufWrite) {
            newBuffer[newBufWrite] = currentBuffer[bufRead];
            newBufWrite++;
            bufRead++;
        }

        currentBuffer = newBuffer;
        bufWrite = newBufWrite;
        bufRead = 0;
        newBufWrite = null;
    }

    // appending buffer
    for (i=0; i<dataBuffer.length; i++) {
        currentBuffer[bufWrite] = dataBuffer[i];
        bufWrite ++;
    }

    // if beginning of message not acknowleged
    if (mSize === null && (bufWrite - bufRead) >= 2) {
        mSize = currentBuffer.readUInt16LE(bufRead);
    }

    // if difference between read and write is greater or equal to message mSize + 2
    // +2 for the integer holding the message size
    // this means that a full message is in the buffer and needs to be extracted
    while ((bufWrite - bufRead) >= mSize+2) {
        bufRead += 2;
        var messageBuffer = new Buffer(mSize);

        for(i=0; i<messageBuffer.length; i++) {
            messageBuffer[i] = currentBuffer[bufRead];
            bufRead++;
        }

        // this is where the message buffer would be passed to the router
        router(session, messageBuffer);
        messageBuffer = null;

        // seeinf if another message length indicator is in the buffer
        if ((bufWrite - bufRead) >= 2) {
            mSize = currentBuffer.readUInt16LE(bufRead);
        }
        else {
            mSize = null;
        }
    }
});
}

【问题讨论】:

  • 您使用什么来衡量服务器内存使用情况?如果做得不好,这可能是一件很难正确测量的事情,而且很容易被系统缓存和分页误导。
  • @jfriend00 我在我的 Windows 7 上工作,所以只是普通的旧任务管理器。我肯定存在泄漏,因为如果我让客户端向服务器发送垃圾邮件大约 10-15 分钟,服务器将使用超过 1 gig 的内存!并且它在客户端开始发送垃圾邮件之前的初始状态约为 50kb.. 你可以非常清楚地看到它在上升
  • router() 函数有什么作用?您是否在断开连接事件中清除会话引用?
  • @jfriend00 路由器功能基本上会诊断消息的类型并将其发送到适当的事件处理程序(即,它是移动消息或身份验证消息/基本上是游戏内容),是的,我正在设置会话变量在套接字关闭事件上为空,即使它不应该真的很重要,因为会话变量是在连接范围内创建的,无论如何都会在关闭时清除..我现在将尝试注释掉我的路由器功能和再次进行测试以确保泄漏专门在这部分代码中
  • 我看到我正在创建的(网络)套接字服务器有类似的行为。 linux中的内存泄漏比windows更严重。我还没有找到任何解决方案。一个建议是最后将 dataBuffer 设置为 null,它应该是一点点。

标签: javascript node.js memory-leaks tcp buffer


【解决方案1】:

缓冲区帧序列化协议 (BUFSP) https://github.com/teambition/bufsp 您可能想要:将消息编码到缓冲区,写入 TCP,接收 TCP 流缓冲区并将其拆分为消息。

【讨论】:

  • 它是否也允许同时发送消息(例如在发送大文件的同时发送消息)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 2016-01-01
  • 1970-01-01
  • 2011-03-22
相关资源
最近更新 更多