FreeOSMemory()正在制作中

Pum*_*eed 6 garbage-collection memory-leaks go

我在一个包含tcp服务器的包中使用goroutine.大部分时间的响应非常繁重,但是当例程结束时,它不会从内存中清除.

func Handle() {
    service := ":7777"
    tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
    checkError(err)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)
    defer listener.Close()

    for {
        conn, err := listener.Accept()
        checkError(err)
        go handleRequest(conn, db)

    }
}

func handleRequest(conn net.Conn, db *sql.DB) {
    message := make([]byte, 0, 4096)
    tmp := make([]byte, 256)
    n, err := conn.Read(tmp)
    if err != nil {
        if err != io.EOF {
            fmt.Println("read error:", err)
        }
    }
    message = append(message, tmp[:n]...)
    fmt.Println("Message Received:", string(message))
    // do something to get resp
    conn.Write(append(resp, []byte("\n")...))
    conn.Close()
    debug.FreeOSMemory()
    return
}
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,响应很大,并且goroutine使用10%的内存,这没关系,因为我从数据库中获得170.000个用户并将结果解析为JSON.但是当handleRequest和它仍在内存中时,如果我没有使用它debug.FreeOsMemory().我怀疑这是一个很好的方法,因为它是在调试pacakge所以我的问题是它是一个很好的方法来清空goroutines正在使用的内存?我对它进行了测试,因此它不会对系统产生影响并且运行良好.如果没有,有什么好办法?我等不及GC了吗?!我读了这个,这就是为什么我开始使用它,在第一个答案中有最后一个建议.

icz*_*cza 7

Go运行时不会立即将空闲内存释放回操作系统,效率很低.在这里阅读更多相关信息:Golang - 一旦被bytes.Buffer占用,就无法释放内存.

你应该让Go运行时处理这个.如果你的应用程序在没有通话的情况下是不稳定的debug.FreeOsMemory(),那么即使它"看似"有帮助,也有一些更大的问题你不应该用它来掩盖.它甚至可能使事情变得更糟,好像提供请求确实需要大量内存(在完成请求时GC正确释放),调用FreeOsMemory()只会将其返回到运行时必须要求的操作系统/在提供另一个请求时再次分配.如果您还没有将其交还给操作系统,它将可用于下一个请求...

尝试降低请求处理程序的内存要求.如果不可能(可疑),则限制可能同时提供大量内存的请求数.

看到这个问题+回答如何做到这一点:Go Webserver的流程管理

另外:这是Go中惯用的工作线程池吗?