Go Performance Optimization Analysis Artefato——pprof|Youth Training Camp Notes

Este é o nono dia da minha participação na Atividade de Criação de Notas Companheiras do "Quinto Acampamento de Treinamento Juvenil"

prefácio

O conteúdo principal deste artigo é o ajuste de desempenho do Go, ferramenta de análise de desempenho - introdução do pprof, processo de amostragem do pprof e análise de princípios.

Introdução

Em projetos reais, todos sabemos que a otimização é muito importante. Com o desenvolvimento iterativo no trabalho, a otimização do código deve ser realizada moderadamente e não excessivamente. A seguir estão os princípios de otimização para referência.

Princípios de otimização e ajuste de desempenho:

  • Confie em dados, não em suposições
  • Para localizar os maiores gargalos em vez de galhos
  • Não otimize prematuramente
  • não otimize demais

ferramenta de análise de desempenho

Queremos saber onde e quanto o aplicativo consome.Existe CPUalguma Memoryferramenta para detectá-lo?

pprofÉ uma ferramenta que pprofpode ser usada para visualizar e analisar dados de análise de desempenho. A seguir apresentaremos o pprof e uma introdução simples ao seu uso.

pprofÉ uma poderosa ferramenta de análise de desempenho que pode capturar dados de status de execução multidimensionais. GoEle integra ferramentas de amostragem no nível da linguagem e pode obter informações de execução como , , e profileassim por diante durante a execução do programa . Isso envolverá pacotes como , e get Os dados vêm em duas formas: formal e gerado por documento.cpuheapblocktracesruntime/pprofnet/http/pprofprofilewebprofile

imagem.png

combate pprof

construção do projeto

Para criar um projeto de pprofprática, o githubprojeto de código aberto anterior é usado aqui. Este projeto incorporou alguns códigos de bomba com antecedência, resultando em problemas de desempenho observáveis. A execução deste projeto ocupará o 1CPUnúcleo e o excesso de 1GBmemória.

Endereço do projeto de código aberto: github.com/wolfogre/go…

Depois de clonar o projeto, insira-o no terminal go run main.gopara executar o projeto.

visualização do indicador

打开浏览器,输入地址 http://localhost:6060/debug/pprof 即可,如图。

imagem.png

从页面中可以查到,内存、block、协程、堆等分配的情况以及锁的操作等。

CPU

首先看一下CPU的运行情况,打开电脑自带的活动管理器,可以看到此项目在我的电脑上占了48%的CPU。

imagem.png

pprof在每运行一段时间后,就会把运行信息输出到文件中,我们可以通过命令来获取文件。

在终端中输入命令,获取文件:

go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
复制代码

imagem.png

topN

命令:top

用于查看占用资源最多的函数

imagem.png

参数说明:

  • flat: 当前函数本身的执行耗时
  • flat%flatCPU总时间的比例
  • sum%: 上面每一行的flat%总和
  • cum: 当前函数本身加上其周期函数的总耗时
  • cum%cumCPU总时间的比例

从图中可以看到,Flat列有的是0,有的不是0,那么Flat在什么情况下等于Cum?什么情况下等于0呢?

根据上述参数说明,可以知道:

  • Flat == Cum,说明函数中没有调用其他函数
  • Flat == 0,说明函数中只有其他函数的调用

通过top命令,得出Eat函数是最消耗CPU的,下面介绍如何定位到代码的具体行。

list

命令:list

可以根据指定的正则表达式查找代码行

imagem.png

输入命令list Eat,从输出结果里可以看到对应的文件为tiger.go,而且具体的代码行为24行的for循环。

web

有时候根据命令行查看结果不是很直观,pprof还提供了可视化的查看方式。

命令: web

将调用关系生成可视化文件,可以输出可视化调用量以及每个节点的资源占用数据。

imagem.png

找到代码进行更改,将循环次数改小一些,再次启动项目,查看资源占用情况,可以发现CPU已经没有那么高了。

imagem.png

imagem.png

Heap

经过代码的改造,可以发现CPU的问题已经解决了,但是内存使用还是很高。

imagem.png

这次直接以可视化的方法查看,输入以下命令,打开堆内存的占用情况:

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
复制代码

打开之后,会出现一下界面:

imagem.png

从上图我们一眼就可以看出,Mouse这个对象的Steal方法占用的内存最多。

打开View->Source视图,还可以看到具体的代码文件以及对应的行数。 imagem.png

找到对应的代码,将代码进行注释,然后看下资源占用情况。

注释掉mouse.go文件的第50行。 imagem.png

重新运行项目,查看资源占用已经很低了。 imagem.png

采样说明,SAMPLE菜单中有几个选项,对应说明如下:

  • alloc_objects: 程序累计申请的对象数
  • alloc_space: 程序累计申请的内存大小
  • inuse_objects: 程序当前持有的对象数
  • inuse_space: 程序当前占用的内存大小

协程

goroutine泄露也会导致内存泄露

以可视化的方法查看,输入以下命令,打开堆内存的占用情况:

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
复制代码

imagem.png

火焰图说明:

  • 由上到下标识调用顺序
  • 每一块代表一个函数,越长代表占用CPU时间更长
  • 火焰图是动态的,支持点击块进行分析

切换到Source视图,查看代码具体位置。

imagem.png

可以看出wolf.go文件里的第34行,协程里进行了睡眠30s,修改此处代码即可修复该问题。

mutex

通过pprof查看锁相关问题,比如加锁时间长等。

执行命令:

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
复制代码

输出界面如下:

imagem.png

切换到代码视图:

imagem.png

可以发现,wolf.go文件里在释放锁前,进行了睡眠操作,对此处代码进行修改即可修复问题。

block

检查代码中是否存在阻塞,执行命令:

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
复制代码

输出界面如下: imagem.png

切换到Source视图,可以看到cat.go文件里存在阻塞行为: imagem.png

同样的,通过top命令也可以看到存在问题的文件。 imagem.png

pprof原理

下面介绍一下pprof的采样过程以及实现原理。

CPU

采样对象:函数调用和他们占用的时间

采样率:100次/秒,固定值

采样时间:从手动启动到手动结束

imagem.png

采样详细流程如下:

imagem.png

流程说明:

  • 操作系统:每10ms向进程发送一次SIGPROF信号
  • 进程:每次接收到SIGPROF信号会记录调用堆栈
  • 写缓冲:每100ms读取已经记录的调用栈并写入输出流

堆内存

堆内存采样过程如下:

  • 采样程序通过内存分配器在堆上分配和释放内存,记录分配/释放的大小和数量
  • 采样率:每分配512KB记录一次,可在运行开头修改,1为每次分配均记录
  • 采样时间:从程序运行开始到采样时
  • 采样指标:alloc_space, alloc_objects, inuse_space, inuse_objects
  • 计算方式:inuse = alloc - free

协程&线程创建

协程和线程创建在实现上非常的相似,都是会在STW之后,遍历所有goroutine/所有线程的列表并输出堆栈,最后Start The World继续运行。这个采样是立刻触发的全量记录,可以通过比较两个时间点的差值来得到某一时间段的指标。

协程(Goroutine)

记录所有用户发起且在运行中的goroutine(即入口非runtime开头的)runtime.main的调用栈信息

线程创建(ThreadCreate)

记录程序创建的所有系统线程的信息

协程和线程创建的采样流程如下:

imagem.png

Block&Mutex

阻塞和锁竞争这两个指标在流程和原理也非常相似,这两个采样记录的都是对应操作发生的调用栈、次数和耗时,不过这两个指标的采样率含义并不相同。

A taxa de amostragem da operação de bloqueio é um "limiar", e a operação de bloqueio que consome mais do que o tempo limite será gravada, e 1 significa que todas as operações serão gravadas.

A taxa de amostragem da competição de bloqueio é uma "proporção". Durante o tempo de execução, apenas uma proporção fixa de operações de bloqueio será registrada por meio de números aleatórios e 1 significa que cada operação será gravada.

Operações de amostragem para operações de bloqueio:

  • O número e o tempo gasto nas operações de bloqueio de amostragem
  • Taxa de amostragem: Somente quando o tempo de bloqueio exceder o limite, ele será registrado e 1 é registrado para cada bloqueio

Operações de amostragem para competição de bloqueio:

  • Amostragem do número de vezes e tempo gasto na competição por fechaduras
  • Taxa de amostragem: grava apenas uma proporção fixa de operações de bloqueio, 1 para cada bloqueio é registrado

O processo de amostragem de bloqueio e competição de bloqueio é o seguinte:

imagem.png

Resumir

O conteúdo principal deste artigo é a ferramenta de ajuste e análise de desempenho Go - pprof, que pproffornece métodos de solução de problemas, como linha de comando e visualização. Este artigo verifica os problemas de desempenho existentes no código por meio da operação real do pprofcódigo CPU. Problemas em vários aspectos, como como memória, pilha, co-rotina block, bloqueio, etc.

Embora o exemplo seja relativamente simples, ele nos permite aprender rapidamente como usar pprofa ferramenta e estabelece uma boa base para solução de problemas e otimização de desempenho no futuro.

citar

Ferramenta de análise de otimização de desempenho

Casos Práticos de Ajuste de Desempenho

おすすめ

転載: juejin.im/post/7193865759825592375