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了吗?!我读了这个,这就是为什么我开始使用它,在第一个答案中有最后一个建议.
Go运行时不会立即将空闲内存释放回操作系统,效率很低.在这里阅读更多相关信息:Golang - 一旦被bytes.Buffer占用,就无法释放内存.
你应该让Go运行时处理这个.如果你的应用程序在没有通话的情况下是不稳定的debug.FreeOsMemory(),那么即使它"看似"有帮助,也有一些更大的问题你不应该用它来掩盖.它甚至可能使事情变得更糟,好像提供请求确实需要大量内存(在完成请求时GC正确释放),调用FreeOsMemory()只会将其返回到运行时必须要求的操作系统/在提供另一个请求时再次分配.如果您还没有将其交还给操作系统,它将可用于下一个请求...
尝试降低请求处理程序的内存要求.如果不可能(可疑),则限制可能同时提供大量内存的请求数.
看到这个问题+回答如何做到这一点:Go Webserver的流程管理