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 }
以上是无法释放内存字节缓冲区的详细内容。更多信息请关注PHP中文网其他相关文章!