在Golang我有一些http响应,我有时忘记打电话:
resp.Body.Close()
Run Code Online (Sandbox Code Playgroud)
在这种情况下会发生什么?会有内存泄漏吗?defer resp.Body.Close()
获取响应对象后立即放入是否安全?
client := http.DefaultClient
resp, err := client.Do(req)
defer resp.Body.Close()
if err != nil {
return nil, err
}
Run Code Online (Sandbox Code Playgroud)
如果有错误怎么办,可能resp
或者resp.Body
是零?
Jim*_*imB 77
在这种情况下会发生什么?会有内存泄漏吗?
这是资源泄漏.连接可以保持打开状态,在这种情况下,不会释放文件描述符.
获取响应对象后立即放入resp.Body.Close()也是安全的吗?
不,请按照文档中提供的示例进行操作,并在检查错误后立即将其关闭.
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
Run Code Online (Sandbox Code Playgroud)
从http.Client
文档:
出错时,可以忽略任何响应.只有在CheckRedirect失败时才会出现带有非零错误的非零响应,即使这样,返回的Response.Body也已关闭.
如果Response.Body
不使用Close()
方法关闭,则不会释放与fd关联的资源.这是资源泄漏.
Response.Body
来自回复来源:
关闭Body是调用者的责任.
因此没有绑定到对象的终结器,必须明确关闭它.
出错时,可以忽略任何响应.只有在CheckRedirect失败时才会出现带有非零错误的非零响应,即使这样,返回的Response.Body也已关闭.
resp, err := http.Get("http://example.com/")
if err != nil {
// Handle error if error is non-nil
}
defer resp.Body.Close() // Close body only if response non-nil
Run Code Online (Sandbox Code Playgroud)
小智 6
起初,描述符永远不会关闭,如上所述。
更重要的是,golang 将缓存连接(使用persistConn
struct 来包装)以重用它,如果DisableKeepAlives
为 false。
在 golang 中使用client.Do
方法之后,go 将运行 goroutinereadLoop
方法作为步骤之一。
所以在 golang http 中transport.go
,apconn(persistConn struct)
不会被放入idleConn
通道,直到 req 在readLoop
方法中取消,并且这个 goroutine( readLoop
method) 将被阻塞,直到 req 取消。
如果你想了解更多,你需要看看readLoop
方法。