为了账号安全,请及时绑定邮箱和手机立即绑定

http.Response.Body 复制导致内存使用量大幅增加

http.Response.Body 复制导致内存使用量大幅增加

Go
精慕HU 2021-11-08 10:28:33
所以我试图从 http.Response 中获取响应正文,进行一些操作,然后将其设置回来。这是我第一次尝试在不耗尽 http.Response 的情况下将其取出:bodyBytes, err := ioutil.ReadAll(resp.Body)if err != nil {    // err} else {    cachedBody := string(bodyBytes)    // Restore the io.ReadCloser to its original state    // This is causing huge increases in memory usage.    resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))}如果我发送 500 个请求,响应大小为 1mb(一大块 JSON,但它可以是任何格式,不仅是 JSON),服务器内存使用量上升到约 400mb,并且不会回落。这是正常的吗?上面的代码有问题吗?我是否错过了释放记忆的东西?defer resp.Body.Close() 没有效果。谢谢!编辑 1这是代理的简单版本的要点,包括建议的近距离通话。如果位于 localhost:3000(它代理的位置)的服务器返回大量响应,内存使用量将迅速增加。就我而言,我返回一个 1mb json 文件,通过 go 代理发送 500 个请求将内存使用量增加到 400mb 左右。Go 代理:https ://gist.github.com/marbemac/300c4c376171cbd27cc3一个简单的节点服务器,它在同一目录中返回一个名为 large_response.json 的文件。https://gist.github.com/marbemac/55aaa78f5858484d33f6
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

使用后必须关闭主体。参考这个

请注意,在使用新值defer resp.Body.Close()重新分配 后会调用resp.Body


查看完整回答
反对 回复 2021-11-08
?
BIG阳

TA贡献1859条经验 获得超6个赞

ioutil.NopCloser使Close()什么都不做。如果你推迟关闭,你永远不会真正关闭它。阅读后立即关闭。


bodyBytes, err := ioutil.ReadAll(resp.Body)

if err != nil {

    // err

resp.Body.Close()

cachedBody := string(bodyBytes)

// Close() does nothing after this

resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

同样在 Go 中,您通常可以忽略它,else因为您可能应该在if上面返回错误或处理它。


像这样的事情有时也sync.Pool很好,因为您不断回收巨大的缓冲区,请检查它在net/http包中的使用方式作为示例。


查看完整回答
反对 回复 2021-11-08
  • 2 回答
  • 0 关注
  • 269 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信