关于【net tcp socket】write方法大量内存泄露的问题
发布于 8 年前 作者 guanzhongdaoke 5030 次浏览 来自 问答

HI,ALL: 最近在用net的TCP SOCKET来做一个网关中转服务器,面临的场景是:大量的TCP长连接,频繁的数据交互(每个链接没秒10个包,至少需要维持5000链接)。 由于我的数据都是自定义格式的二进制流,所以收发数据全部BUFFER结构。 同时,为了尽可能减少BUFFER的申请,我自己做了一个BUFFER的缓冲池POOL,内部全部是定长的Slow BUFFER,每次发送数据的时候,从POOL内取一个BUFFER,放入数据,然后交个write方法,等待发送完成之后,在回收回POOL。类似代码如下: // 发送消息(主要是逻辑层的消息数据)

  1. SendData:function(data)
  2. {
  3. // 发送数据
  4. var len = data.length;
  5. var node = MemoryManager.GetNode(len+4);
  6. // 写入数据
  7. // 发送
  8. this.mSocket.write(node.slice(0, len), function()
  9. {
  10. MemoryManager.ReleaseNode(node);
    
  11. });
  12. },

经过大量的测试(尤其是模拟用户链接会出现各种异常断线,关闭SOCKET等情况): 1:发现我每次write申请的BUFFER个数和write结束后回调里面回收的BUFFER个数对不上,如果当前链接一旦出现异常断开后,很多以发起write的操作不会callback,导致了内存泄露(不知道是不是BUG??) 现在遇到了大量的内存泄露问题,且没有办法很好的解决,大家有更好的方案吗?

5 回复

待会会有 aliyun 的人来让你用 alinode … 手动 dog

请使用alinode,分分钟告诉你哪里出问题了 From Noder

callback 不触发,就是出错,看你是否监听error事件,或者设置timeout针对异常连接

谢谢大家的回复,昨晚经过大量的测试证明:、 1:SOCKET的write callback仅仅在数据发送成功才会回调,如果存在大量的write请求,SOCKET一旦出错,后面的就不会再触发callback. 2:现在的做法是每次发起write的时候,把对应的BUFFER都存在一个队列里面,然后callback的时候,从队列弹出第一个BUFFER,然后回收(因为TCP的有序的,我们发送的所有数据也都会有序的触发callback,所以顺序没问题;一旦出错,就把队列里面剩余的BUFFER回收)

这部分其实是个大坑,如果用SOCKET读写大量BUFFER的话,一定要注意

回到顶部