如果我不取消上下文会怎么样?

sta*_*wer 17 go

我有以下代码:

func Call(ctx context.Context, payload Payload) (Response, error) {
    req, err := http.NewRequest(...) // Some code that creates request from payload
    ctx, cancel = context.withTimeout(ctx, time.Duration(3) * time.Second)
    defer cancel()
    return http.DefaultClient.Do(req)
}
Run Code Online (Sandbox Code Playgroud)

如果我没有放入defer cancel()那里会怎么样? go vet警告过这个

context.WithTimeout返回的cancel函数应该被调用,而不是被丢弃,以避免上下文泄漏

上下文将如何泄露以及这将产生什么影响?谢谢

Kae*_*dys 29

如果您无法取消上下文,则创建WithCancel或WithTimeoutgoroutine将无限期地保留在内存中(直到程序关闭),从而导致内存泄漏.如果你经常这么做,你的记忆就会大大增加.最好的做法是defer cancel()在通话后立即使用WithCancel()WithTimeout()

  • 这似乎不再是事实了?我做了一些测试,goroutine会正常释放。泄漏的不是 goroutine,而是子上下文。在不取消上下文的情况下,所有子上下文都将保留在内存中,直到父上下文被取消。https://play.golang.org/p/8lJ7nQOj45Y (3认同)

use*_*000 20

如果使用WithCancelgoroutine将无限期地保留在内存中。但是,如果您使用WithDeadlineWithTimeout不调用取消,goroutine只会被保留到计时器到期。

但这仍然不是最佳实践,最好在完成资源后立即调用取消。