卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34170本站已运行391

无法释放内存字节缓冲区

无法释放内存字节缓冲区

问题内容

go 1.18.1

pprof报告

3549.93kb 49.73% 49.73%  3549.93kb 49.73%  src/lag_monitor.publishlagmetrictodatadog
     514kb  7.20% 56.93%      514kb  7.20%  bufio.newwritersize
  512.88kb  7.18% 64.11%   512.88kb  7.18%  encoding/pem.decode
  512.69kb  7.18% 71.30%  1536.98kb 21.53%  crypto/x509.parsecertificate
  512.50kb  7.18% 78.48%   512.50kb  7.18%  crypto/x509.(*certpool).addcert

这段代码似乎没有释放内存,根据pprof,下面的函数是消耗内存最多的函数。内存图

func caller() {
 events := make([]string, 0)
 //....
 PublishLagMetricToDataDog(ctx, strings.Join(events, ","))
}

func PublishLagMetricToDataDog(ctx context.Context, events string) error {
msg := `{
    "series": [%v]
}`
b := []byte(msg)
resp, err := http.Post("https://api.datadoghq.com/api/v1/series?api_key="+env.GetDataDogKey(), "application/json", bytes.NewBuffer(b))
if err != nil {
    logger.Error(ctx, "Error submitting event to datadog, err = ", err)
    return err
}
logger.Info(ctx, resp)
return nil
}

上面的函数是在循环中调用的。由于没有全局变量,也没有对 publishlagmetrictodatadog 中的字节切片的引用,因此我无法查明内存泄漏。我读到了有关 reset() 和 truncate() 的内容,但这不会释放底层内存。


正确答案


您必须关闭收到的每个 http 响应的响应正文。不这样做可能会导致资源泄漏,就像您所观察到的那样。

解决方案:

    resp, err := http.Post("https://api.datadoghq.com/api/v1/series?api_key="+env.GetDataDogKey(), "application/json", bytes.NewBuffer(b))
    if err != nil {
        logger.Error(ctx, "Error submitting event to datadog, err = ", err)
        return err
    }
    logger.Info(ctx, resp)
    _ = resp.Body.Close() // <--- Add this
    return nil
}
卓越飞翔博客
上一篇: 如何打印与前面的数字不同的数字?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏