golang 如何排查和定位GC问题

ssdut_buster · · 4021 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

    最近在做文本处理的时候遇到一个很奇怪的现象。串行执行脚本可能只需要几秒钟,但是如果想给每行开个协程并发处理的话,执行时间却从几十秒到几十分钟不等,关键是执行的过程中cpu的占用并不高。经过一系列的分析之后确认是gc导致的。所以想讲一下排查gc问题的一些小技巧,之后也会给出一些case:

    一。如何查看程序运行过程中的GC信息呢?

    设置gctrace的变量值为1即可,这个既可以设置成环境变量,也可以选择按如下方式执行:

GODEBUG=gctrace=1  go run main.go
//GODEBUG=gctrace=1 ./main

GODEBUG=gctrace=1 代表只针对这个进程开启gc追踪功能。程序输出如下:

       

    对于上面每一行每一列的具体含义:

gc 1 @0.038s 1%: 0.55+0.12+0.081 ms clock, 2.2+0/0.42/1.1+0.32 ms cpu, 4->4->0 MB, 5 MB goal, 4 P。

1 表示第一次执行

@0.038s 表示程序执行的总时间

1% 垃圾回收时间占用总的运行时间百分比

0.018+1.3+0.076 ms clock 垃圾回收的时间,分别为STW(stop-the-world)清扫的时间, 并发标记和扫描的时间,STW标记的时间

0.054+0.35/1.0/3.0+0.23 ms cpu 垃圾回收占用cpu时间

4->4->3 MB 堆的大小,gc后堆的大小,存活堆的大小

5 MB goal 整体堆的大小

4 P 使用的处理器数量

    打开了GCTRACE之后对于gc执行的时间点、执行次数以及耗时可能已经有了初步的了解,但是对什么地方耗用大量内存并造成大量延迟可能并不清除。

二。如何定位gc问题所在?

    这一点主要使用pprof来实现。开启pprof也特别简单,用net/http/pprof包可以快速实现。只需要在之前的代码中加下面三行就可以:

import (
    "net/http"
    _ "net/http/pprof"
)
go func() {
            log.Println(http.ListenAndServe("localhost:8081", nil))
}()

    在程序启动之后,只需要在命令行或者浏览器输入以下命令即可:

go tool pprof  http://127.0.0.1:8081/debug/pprof/heap       //查看堆的使用,即内存使用情况
go tool pprof  http://127.0.0.1:8081/debug/pprof/profile    //查看cpu耗时,会详细列出每个函数的耗时
go tool pprof  http://127.0.0.1:8081/debug/pprof/goroutine  //当前在运行的goroutine情况以及总数

    可以看下profile的输出信息, flat代表单个函数的运行时间,而cum则是累加的时间,也会包括这个函数下面的子函数的累加时间,所以main.main肯定是100%:

        

    如果想看具体的图示的话,可以使用png命令将结果存成图片看,比如:

        

    可以看下生成图片的样子, 有具体的箭头以及每个函数占用的时间或者内存:

     

 

基本目前笔者用到的工具就这两个了,感觉有收获的读者可以自己实验一下。接下来,我会不定期的分享一些遇到的GC问题的case,欢迎一起交流哈。


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:ssdut_buster

查看原文:golang 如何排查和定位GC问题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4021 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传