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

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

问题描述

我在有 tcp 服务器的包中使用 goroutine.大多数时候响应很重,但是当例程结束时,它并没有从内存中清除.

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("
")...))
    conn.Close()
    debug.FreeOSMemory()
    return
}

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

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.

推荐答案

Go 运行时不会立即"将空闲内存释放回操作系统,否则效率会很低.在此处阅读更多相关信息:Golang - 无法释放内存曾经被bytes.Buffer占用.

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.

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

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.

查看这个问题+答案如何做到这一点:流程管理Go 网络服务器

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

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

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

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