FreeOSMemory()在生产中 [英] FreeOSMemory() in production

查看:189
本文介绍了FreeOSMemory()在生产中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在有tcp服务器的软件包中使用goroutines。大多数情况下,响应非常重,但是当程序结束时,它不会从内存中清除。

  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)$ b $ 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))
//做一些事情来获得响应
conn.Write(append(resp,[] byte(\\\
))。 ..))
conn.Close()
debug.FreeOSMemory()
返回$ b $所以在这种情况下,响应很大,并且使用10%的内存的goroutine,那好吧,因为我从数据库中获得170.000个用户并将结果解析为JSON。但是,当handleRequest和它仍然在内存中,如果我不使用 debug.FreeOsMemory()。我怀疑这是一种很好的方法,因为它在调试平台中,所以我的问题是清空存储器的一个好方法?我对它进行了测试,因此它对系统没有影响,并且运行得非常好。如果不是,那么好的方法是什么?我不能等待GC来清除它?!我阅读了,这就是为什么我开始使用它,在第一个答案中有最后一个建议。

解决方案

Go运行时不释放可用内存回OS 立即,这将是低效的。阅读更多关于它的信息: Golang - 不能自由内存一次被bytes.Buffer占据。



你应该让Go运行时处理这个问题。如果您的应用程序不稳定而未调用 debug.FreeOsMemory() ,即使看起来有所帮助,也存在更大的问题,您不应该掩饰这个问题。它甚至可能让事情变得更糟,就好像提供请求确实需要大量内存(在完成请求时由GC正确释放),调用 FreeOsMemory()只会将其返回到运行时在再次请求服务器时再次请求/分配的OS。如果你没有把它交给操作系统,它可以用于下一个请求......



尽量减少请求处理程序的内存需求。如果这是不可能的(可疑),那么限制需要大容量内存的请求数量可能会同时服务。



看到这个问题+答案如何做到这一点:< a href =https://stackoverflow.com/questions/37529511/process-management-for-the-go-webserver/37531953#37531953> Go Webserver的流程管理



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


I am using goroutines in a package where there is a tcp server. The response most of the time is very heavy, but when the routines end it is not cleared from the memory.

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
}

So in this case the response is big, and a goroutine using 10% of the memory, thats okay, because I'm getting 170.000 users from the database and parse the result to JSON. But when the handleRequest and it is still in the memory, if I'm not using debug.FreeOsMemory(). I have doubts it is a good way to do it because it is in the debug pacakge so my question is it a good way to empty the memory what the goroutines are using? I tested it so it is not affected to the system and working very well. If not, what is the good way? I can't wait the GC for clear it up?! I read this and this is why I started to use it, in the first answer there is the last suggestion.

解决方案

The Go runtime does not release free memory back to the OS "immediately", it would be inefficient. Read more about it here: Golang - Cannot free memory once occupied by bytes.Buffer.

You should let the Go runtime handle this. If your app is unstable without calling debug.FreeOsMemory(), there are bigger problems which you shouldn't cover up with this even if it "seemingly" helps. It may even make things worse, as if serving a request does require a large amount of memory (which is properly freed by the GC when done with the request), calling FreeOsMemory() will just return it to the OS which the runtime will have to ask for / allocate again when serving another request. Should you have not handed it back to the OS, it would be available for the next request...

Try to decrease the memory requirement of the request handler. If it is not possible (questionable), then limit the number of requests requiring large memory that may be served concurrently.

See this question+answer how to do that: Process Management for the Go Webserver

Also: Is this an idiomatic worker thread pool in Go?

这篇关于FreeOSMemory()在生产中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆