go语言服务端内存持续增长,求解惑!

wuyingsong · 2015-02-20 12:50:38 · 5548 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2015-02-20 12:50:38 的主题,其中的信息可能已经有所发展或是发生改变。

最近用golang开发了一个socket服务端,主要逻辑就是接收客户端发来的数据解析后存入opentsdb中,但是跑一段时间后发现内存就会增长,而且不会被gc回收,初步判定是由于大量make []byte 导致内存不释放,代码如下,求高人解惑?

func StartTCP() error {
    tcp_addr, _ := net.ResolveTCPAddr("tcp4", tcp_listen)
    listener, err := net.ListenTCP("tcp4", tcp_addr)
    if err != nil {
        return err
    }
    defer listener.Close()
    log.Info("start tcp listen on %s", tcp_listen)
    for {
        conn, err := listener.AcceptTCP()
        if err != nil {
            log.Error("accept error %s", err.Error())
            continue
        }
        log.Info("new session create %s", conn.RemoteAddr().String())
        go HandlerConn(conn)
    }
}


func ReadPacket(conn *net.TCPConn) []byte {
    head := make([]byte, 4)
    _, err := io.ReadFull(conn, head)
    if err != nil {
        return nil
    }
    size := binary.BigEndian.Uint32(head)
    data := make([]byte, size)
    _, err = io.ReadFull(conn, data)
    if err != nil {
        return nil
    }
    return data
}


func HandlerConn(conn *net.TCPConn) {
    addr := conn.RemoteAddr().String()
    defer func() {
        if err := conn.Close(); err != nil {
            log.Error("close session error %s", err.Error())
        } else {
            log.Info("session closed %s", addr)
        }
    }()
    data := ReadPacket(conn)
    if len(data) == 0 {
        log.Warn("empty data")
        return
    }
    go HandlerMsg(conn, data, t)
}

附pprof信息

(pprof) top
9.92GB of 9.93GB total (  100%)
Dropped 359 nodes (cum <= 0.05GB)
  flat  flat%   sum%        cum   cum%
9.92GB   100%   100%     9.92GB   100%  main.ReadPacket
     0     0%   100%     9.92GB   100%  main.HandlerConn
     0     0%   100%     9.92GB   100%  runtime.goexit

(pprof) list main.ReadPacket
Total: 9.93GB
ROUTINE ======================== main.ReadPacket in /tmp/td-        server/tcp_server.go
9.92GB     9.92GB (flat, cum)   100% of Total
     .          .     30:       go HandlerConn(conn)
     .          .     31:   }
     .          .     32:}
     .          .     33:
     .          .     34:func ReadPacket(conn *net.TCPConn) []byte {
     .          .     35:   head := make([]byte, 4)
     .          .     36:   _, err := io.ReadFull(conn, head)
     .          .     37:   if err != nil {
     .          .     38:       return nil
     .          .     39:   }
     .          .     40:   size := binary.BigEndian.Uint32(head)
9.92GB     9.92GB     41:   data := make([]byte, size)
     .          .     42:   _, err = io.ReadFull(conn, data)
     .          .     43:   if err != nil {
     .          .     44:       return nil
     .          .     45:   }
     .          .     46:   return data
     .          .     47:}

上次重启过后运行了一周目前很稳定,pprof发现内存占用和之前完全不一样,很奇怪

最新pprof

(pprof) top
3201.70kB of 3201.70kB total (  100%)
Dropped 362 nodes (cum <= 16.01kB)
Showing top 10 nodes out of 19 (cum >= 1536.14kB)
      flat  flat%   sum%        cum   cum%
 1024.11kB 31.99% 31.99%  1024.11kB 31.99%  main.(*Device).getIndex
  641.34kB 20.03% 52.02%   641.34kB 20.03%  main.init_config
  512.14kB 16.00% 68.01%   512.14kB 16.00%  mcommoninit
  512.08kB 15.99% 84.01%   512.08kB 15.99%  database/sql.(*DB).addDepLocked
  512.03kB 15.99%   100%   512.03kB 15.99%  bufio.(*Reader).ReadString
         0     0%   100%   512.08kB 15.99%  database/sql.(*DB).Query
         0     0%   100%   512.08kB 15.99%  database/sql.(*DB).QueryRow
         0     0%   100%   512.08kB 15.99%  database/sql.(*DB).conn
         0     0%   100%   512.08kB 15.99%  database/sql.(*DB).query
         0     0%   100%  1536.14kB 47.98%  main.(*Device).CollectHW
(pprof)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5548 次点击  ∙  2 赞  
加入收藏 微博
14 回复  |  直到 2015-03-25 07:48:30
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传