golang  copy

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

golang  copy

​ whoops本尊   ​   2022-06-20 我要评论

前言:

记一次golang使用json进行对象copy的内存溢出问题排查

问题现象:新增的功能,灰度部署在k8s集群的服务,发现机器老是被打崩,因为是灰度,且控制了qps在100多,但是机器却崩溃。通过对灰度机器的监控。发现是内存太高导致机器挂掉。此次回顾一下排查历程。

增加GC次数,从而可以通过pprof去抓取内存使用情况:

将程序的GOGC由原先的2000改为200,从而增加GC次数,然后去抓取内存消耗情况

  • 第一步操作完成,经验证机器可以正常运行,借助gops导出cpu运行图和内存消耗情况
  • ①将编译好的linux版本的gops导入到目标机器上
  • ②执行命令 gops 查看正在运行的程序的pid

  • ③执行命令获取cpu运行状态 gops pprof-cpu 27 
  • ④执行命令获取内存消耗情况 gops pprof-heap 27

执行上述两个命令后,其会生成文件在tmp目录下 :

//⑤将生成的文档下载到本地后,分别执行 
go tool pprof -http=:8080 cpu_profile*
go tool pprof -http=:8081 heap_profile*
//在本地生成可视化

内存的火焰图如下 :

 cpu的火焰图如下:

 通过对火焰图的分析,可以明显的看到json.Marshal 和 json.Unmarshal 有明显的占用问题。跟着火焰图去找寻调用此处的该方法,定位到

此处就不列出runtime.Context对象的具体情况了,你可以理解为里面多处指针,多处切片。反正就是结构体很大 【PS:改天针对大结构体出个压测结果】

发现问题后更换如下代码进行对象copy,注意此拷贝结构体不能有小写字母开头。另外建议尽量少进行对象copy,尽可能的细化到需要copy的地方

/**
 * @Description:深拷贝数据 (慎用--结构体不能有小写字母开头)
 */
func DeepCopy(dst, src interface{}) error {
   var buf bytes.Buffer
   if err := gob.NewEncoder(&buf).Encode(src); err != nil {
      return err
   }
   return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们