go 打开文件句柄_Go中trace包的使用

2023-10-26

Go给我们提供了一个工具trace,可以在运行时启用trace, 并获得程序执行情况的详细视图。

应该怎么使用trace呢?一般有下面三种使用方式

  • 运行go test的时候,带上-trace参数标记, go test -trace=trace.out

  • pprof中获取实时traceimport _ "net/http/pprof"

  • 在代码中编码嵌入trace,

代码中使用, 我写了一个简单的例子:

package main

import (
"io/ioutil"
"log"
"os"
"runtime/trace"
"sync"
)

// 一个简单的例子去演示如何在代码中使用trace包
func main() {
// 1. 创建trace持久化的文件句柄
f, err := os.Create("trace.out")
if err != nil {
log.Fatalf("failed to create trace output file: %v", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatalf("failed to close trace file: %v", err)
}
}()

// 2. trace绑定文件句柄
if err := trace.Start(f); err != nil {
log.Fatalf("failed to start trace: %v", err)
}
defer trace.Stop()

// 下面就是你的监控的程序
// 我简单写了一个文件读写
var wg sync.WaitGroup
wg.Add(2)

// 一个协程用来读文件
go func() {
defer wg.Done()
ioutil.ReadFile(`mxc.txt`)
}()

// 写文件协程
go func() {
defer wg.Done()
ioutil.WriteFile(`mxc_code.txt`, []byte(`码小菜`), 0644)
}()

wg.Wait()
}

运行命令

ce90e027717e8ee60742228e51ae8540.png

会看到生成一个trace.out的文件,打开命令

dd3ad447574d3739827abd65f6d049ba.png

这时候会打开一个浏览器窗口,可以看到

26af8e9ea35f6f34c5bcbf305b40c383.png

工作原理

trace的工作流程非常简单, 标准库会记录Go运行期间的每个事件,例如内存分配, 垃圾收集器(gc)的所有阶段, goroutine何时运行,暂停等等,并将这些信息格式化以供以后显示使用。

  • 在开始记录之前,runtimeSTW,并对当前goroutines的状态进行快照。

0f1ff9fdc7bef2f477f852f4c7deec87.png

  • stw后,收集的事件会放入trace的一个缓冲区,在达到缓冲区最大容量时刷新。下面是整个流程图

 ef9c4ec2d644dd598b3427b61448b5d2.png

  • tracer现在就可以将上面收集的信息dump到输出。所以,当trace开始时,Go会专门为trace启动一个goroutine。这个goroutine会在数据可用时dump记录的数据到输出,在没有数据时park住。如下图:ab9f3ab2616463ce35099d0ad0afe0b0.png

现在的流程就非常清晰了

一旦生成了跟踪信息,就可以用命令go tool trace output.out来完成可视化, 下图是我刚开始那个简单程序的一个trace图,点击图一的View Trace

14bd0f07e55e8b57344de61786c6b416.png

上面的代码相对简单,看不到更多的关于gc的信息,下面我写了一个触发gc的程序

package main

import (
"log"
"os"
"runtime/trace"
"sync"
)

func main() {
// 1. 创建trace持久化的文件句柄
f, err := os.Create("trace.out")
if err != nil {
log.Fatalf("failed to create trace output file: %v", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatalf("failed to close trace file: %v", err)
}
}()

// 2. trace绑定文件句柄
if err := trace.Start(f); err != nil {
log.Fatalf("failed to start trace: %v", err)
}
defer trace.Stop()

// 下面就是你的监控的程序
var wg sync.WaitGroup
wg.Add(2)

go func() {
defer wg.Done()
for i := 0; i < 100; i++ {
_ = make([]int, 0, 20000)
}
}()

go func() {
defer wg.Done()
for i := 0; i < 100; i++ {
_ = make([]int, 0, 10000)
}
}()

wg.Wait()
}

图示很直接。与gc相关的信息,如下图0e02d13459f7f1966d107f7b7fdf65e6.png

下面是一个大致的描述

  • STW 是gc中的两个"停止世界"的阶段。在这两个阶段中,goroutine会停止运行。

d6482b7cd126485f76d16069e2ba1e5e.png

  • GC(idle) 指没有标记内存时的goroutine。

3bbbaf5b622c9d8fdf64c482dbb886cc.png

  • MARK ASSIST 在分配内存过程中重新标记内存(mark the memory)的goroutine。

b4fbee02fa84a5ae5f325946480fa3ec.png

  • SWEEP 垃圾清理

fa310773c5e2694f6ddffde3e5dba635.png

  • GXX runtime.gcBgMarkWorker 是帮助标记内存的专用后台goroutine。

b0655f806449276c03c291fdbbdba378.png

然而,有些Trace并不容易理解:

  • proc start当一个逻辑处理器§与一个线程绑定时被调用。也就是启动新线程或从系统调用恢复

4f88745d55d4702d43735a8a19a80428.png

  • proc stop当线程与当前处理器§分离时,将调用proc stop。当线程发生系统调用被阻塞或线程退出时,就会发生这种情况。

c98993f9b7433c44da42f5654519bb91.png

  • goroutine进行系统调用时,将调用syscall

ec54c7f909d9c9f1ff97b2352746ce73.png

注意:Trace既可以定义和可视化自己的Trace以及也可以追踪标准库中的Trace

用户Traces

用户级别可以定义的Trace具有两个层次级别:

  • 在任务的最高层,有开始和结束

  • 在该区域的子级别上

这里有一个简单的例子:

package main

import (
"context"
"io/ioutil"
"log"
"os"
"runtime/trace"
"sync"
)

// 一个简单的例子去演示如何在代码中使用trace包
func main() {
// 1. 创建trace持久化的文件句柄
f, err := os.Create("trace.out")
if err != nil {
log.Fatalf("failed to create trace output file: %v", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatalf("failed to close trace file: %v", err)
}
}()

// 2. trace绑定文件句柄
if err := trace.Start(f); err != nil {
log.Fatalf("failed to start trace: %v", err)
}
defer trace.Stop()

ctx, task := trace.NewTask(context.Background(), "main start")
var wg sync.WaitGroup
wg.Add(2)

go func() {
defer wg.Done()
r := trace.StartRegion(ctx, "reading file")
defer r.End()

ioutil.ReadFile(`n1.txt`)
}()

go func() {
defer wg.Done()
r := trace.StartRegion(ctx, "writing file")
defer r.End()

ioutil.WriteFile(`n2.txt`, []byte(`42`), 0644)
}()

wg.Wait()
defer task.End()
}

可以通过菜单中的用户自定义任务直接从工具中可视化这些Trace:

950e4a527173868a1e3e6ff165549663.png

也可以记录一些其他的信息到任务:

ctx, task := trace.NewTask(context.Background(), "main start")
trace.Log(ctx, "category", "I/O file")
trace.Log(ctx, "goroutine", "2")

这些日志将在设置任务的goroutine下找到:

18e511436d13ef6681f9eba643eb6066.png

一个简单的性能测试,可以帮助理解Trace对应用程序的影响。一个将带有-trace标志,而另一个则不带-trace。以下是带有ioutil.ReadFile()函数的性能测试的结果,该函数会生成大量事件:

name         time/op
ReadFiles-8 48.1µs ± 0%
name time/op
ReadFiles-8 63.5µs ± 0% // with tracing

在这种情况下,性能影响约为35%,并且可能和应用有关系, 你可以根据你的应用性能来决定要用不用

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go 打开文件句柄_Go中trace包的使用 的相关文章

  • python数据可视化入门(五):饼图,环图,极线图,气泡图

    饼图 plt pie x explode None labels None colors None autopct None 1 labels 设置相对应数据的标签 2 labeldistance 设置标签距离圆心的距离 labeldist
  • 【C++ Primer Plus(第6版)中文版第二章开始学习C++(编程练习题)】

    关于个人学习C Primer Plus的第二章编程练习题 1 编写一个C 程序 它显示您的姓名和地址 2 编写一个C 程序 它要求用户输入一个以long为单位的距离 然后将它转换为码 一long等于220码 3 编写一个C 程序 它使用3个
  • CTF_webshow_web11

    d打开靶机 直接有源码 查看一下
  • Java Swing 经典小游戏之 ———— 黄金矿工

    一 效果预览 项目简介 1 游戏预览 2 玩法简介 1 开局一条红绳 左键让他变长 2 5个金块 分成 大中小 3个石块 3 3种速度 空爪 gt 抓回金块 gt 抓回石块 4 4个得分 获得 得分 大金块 30 中金块 20 小金块 10
  • MCU踩坑记录:SWD复用为GPIO使用,Jflash连不上的问题

    用了某款MCU 由于项目需要用的gpio比较多 只能将SWD烧写口SWD CLK和SWD DIO复用为gpio使用 但是程序一旦跑起来 再用jflash就连不上了 如下图所示 如果MCU有BOOT引脚 可以将BOOT引脚配置为其他启动模式不
  • vue脚手架如何创建vue项目

    vue脚手架如何创建vue项目 1 打开命令行 进入需要创建目录的文件夹 或者在需要创建目录的文件夹进入cmd窗口 1 先查看以下vue脚手架是否下载 命令行输入npm list g 1 2 如果没下载vue脚手架 则输入命令npm ins
  • Java开发人员必知必会的20种常用类库和API

    Java开发人员必知必会的20种常用类库和API 一个有经验的Java开发人员特征之一就是善于使用已有的轮子来造车 Effective Java 的作者Joshua Bloch曾经说过 建议使用现有的API来开发 而不是重复造轮子 在本文中
  • Spring cloud Gateway常用配置

    gateway里的常用配置 前面的例子是通过路径 Path 方式配置路由转发 gateway还还有其他的配置 下面做个简单的介绍 1 路由 route Route 主要由 路由id 目标uri 断言集合 过滤器集合组成 前面的实例用到了id
  • python 获取网页视频

    代码实现 import tkinter import tkinter messagebox import os import os path import you get 获取当前工作目录 path os getcwd 设置当前目录为工作目
  • LeetCode 460. LFU Cache

    原题网址 https leetcode com problems lfu cache Design and implement a data structure for Least Frequently Used LFU cache It
  • 吐血推荐那些提升开发人员工作效率的在线工具

    来源 公众号 作者 Hollis 作为一个Java开发人员 经常要和各种各样的工具打交道 除了我们常用的IDE工具以外 其实还有很多工具是我们在日常开发及学习过程中要经常使用到的 Hollis偏爱使用在线工具 因为个人觉得这样比较方便 本文
  • crontab定时启动scrapy爬虫

    部署到测试环境 并设置定时启动任务 通过FileZille工具 将本地的文件上传到测试服务器上面的python文件夹中 在与spider同级目录下写一个shell脚本 启动所编辑的运行爬虫文件 vi run sh 1 bin sh 2 ex
  • 修改服务器数据库名称,修改服务器数据库名称

    修改服务器数据库名称 内容精选 换一换 弹性云服务器能否ping通华为云关系型数据库实例 如果ping不通 可以查看弹性云服务器和华为云关系型数据库实例是否处于同一个虚拟私有云内 是否使用同一个安全组 如果ping不通 可以查看弹性云服务器
  • Aviator这么丝滑,怎么实现的呢?

    大家好 我是老三 在上期 里我们介绍了轻量级规则引擎AviatorScript的基本用法和一些使用案例 这期我们来研究一下 这么丝滑的规则脚本是怎么实现的 概览 我们先来回顾一个简单的例子 Test public void test 表达式
  • element 模态框内,表单编辑回填的值在关闭时,表单内容无法正确重置问题

    element 表单使用 this refs formName resetFields 进行数据重置 但重置的初始数据是基于表单第一次渲染时的数据为模板 由于点击编辑时 模态框显示与表单内容渲染是同时进行 所以 el form 就认为回填值
  • STM32--TIM定时器(3)

    文章目录 输入捕获简介 频率测量 输入捕获通道 输入捕获基本结构 PWMI的基本结构 输入捕获模式测量PWM频率和占空比 代码 编码器接口 正交编码器 工作模式 接口基本结构 TIM编码接口器测速 代码 输入捕获简介 输入捕获IC Inpu
  • 传奇服务器文件组成,【教程】传奇服务端(版本)的结构以及重要文件功能的概述-A02...

    第A02课 传圌奇私圌服服圌务端 版本 的结构以及重要文件功能的概述 有很多新人根本不了解传圌奇的结构 学习的时候就比较困难 所以才设置了这么一课 以下是服圌务端主要文件位置与用途
  • Qt实现多线程编程的两种方式

    Qt实现多线程编程的两种方式 方式一 继承自QThread类 覆写run函数 此实现方法只有run函数内的代码是运行在子线程内 代码示例 ifndef QDEMOTHREAD H define QDEMOTHREAD H include
  • 自定义控件MeasureSpecs与measure的理解

    MeasureSpace 是android中父view传递给子view的用来描述对子 view布局需求的数据类型 也就是说父布局把它希view的大小以及变化的尺度分装在这个类里 而子view的measure 方法拿到这个数值 则会根据这个数

随机推荐

  • 【基于机器学习的全国降水量预测分析可视化-哔哩哔哩】 https://b23.tv/RsGfqeD

    基于机器学习的全国降水量预测分析可视化 哔哩哔哩 https b23 tv RsGfqeD https b23 tv RsGfqeD
  • Python脚本报错AttributeError: ‘module’ object has no attribute’get’解决方法

    发现代码都没有错 后来是改成这样 def pprint name var get print name var StringVar Label root text 姓名 font 微软雅黑 20 grid inputStr1 Entry r
  • RabbitMQ消息队列(转)

    转自 https www jianshu com p 79ca08116d57 关于消息队列 从前年开始断断续续看了些资料 想写很久了 但一直没腾出空 近来分别碰到几个朋友聊这块的技术选型 是时候把这块的知识整理记录一下了 市面上的消息队列
  • darknet-yolov4编译

    在个人win10上运行darknet yolov4 准备 电脑msi显卡 gtx1050ti 4g 驱动451以上 内存金士顿8g 必须项准备 先安装vs2017 必须勾选c 再cuda 我装了cuda10 0和9 2 上移环境变量 使10
  • 高级数据库总结

    总结 一 总结笔记 首先是我们会用到的几张数据表 1 学习数据库的必要性 时代迎来大数据时代 数据量的庞大已经不足以用人力来计算 为此我们需要一个软件或者一套流程来解决这个问题 那么数据库肯定是最佳选择 学点东西总是好的 2 Mysql数据
  • Netty:option和childOption参数设置说明

    转载 http www jianshu com p 0bff7c020af2 Channel配置参数 1 通用参数 CONNECT TIMEOUT MILLIS Netty参数 连接超时毫秒数 默认值30000毫秒即30秒 MAX MESS
  • [Android][设置最小(大)宽高]

    1 简介 TextView里定义的方法 据说是设置文本区域的宽高 android maxWidth 关联方法 setMaxWidth int 属性说明 设置文本区域的最大宽度 android maxHeight 关联方法 setMaxHei
  • Linux下获取ip、mac、子网掩码、广播地址信息

    get interface c include
  • 随机数算法,SQL

    SELECT FROM prizes config WHERE weight gt SELECT FLOOR RAND MAX weight FROM prizes config order by weight asc LIMIT 1 记录
  • RPM 软件包使用常见问题

    1 如何安装rpm软件包 rmp软件包的安装可以使用程序rpm来完成 执行下面的命令 rpm i your package rpm 其中your package rpm是你要安装的rpm包的文件名 一般置于当前目录下 安装过程中可能出现下面
  • SpringBoot配置文件敏感信息加密-jasypt

    使用过SpringBoot配置文件的朋友都知道 资源文件中的内容通常情况下是明文显示 安全性就比较低一些 打开application properties或application yml 比如mysql登陆密码 redis登陆密码以及第三方
  • Unity-角色互动加分显示的实现

    文章目录 角色互动加分显示的实现 在角色的脚本里设置分数 布置页面以及编译对应的脚本 使用事件委托将两者连接 角色互动加分显示的实现 思路 在角色的脚本里对应该加分的地方用变量统计分数 同时再创建一个ui对象 然后用委派事件获取角色的得分
  • [paper] Hourglass

    Stacked Hourglass Networks for Human Pose Estimation Abstract Hourglass Net是一个进行人体位姿估计的卷积神经网络 也可以用在人脸关键点检测等领域 它结合了身体上的空间
  • WChar_t 字符集的操作函数

    函数介绍 wcslen 类似与char 类型作参数的strlen 函数 用来获取wchar t 变量的长度 不包含终结符 wcscpy 类似与char 类型作参数的strcpy 函数 用来进行wchar t 变量之间的复制 同样的还有 wc
  • Qt应用开发(基础篇)——布局管理 Layout Management

    一 前言 在实际项目开发中 经常需要使用到布局 让控件自动排列 不仅节省控件还易于管控 Qt布局系统提供了一种简单而强大的方式来自动布局小部件中的子小部件 以确保它们充分利用可用空间 所有QWidget子类都可以使用setLayout 设置
  • JavaScript面向对象详解

    声明 本人的所有博客皆为个人笔记 作为个人知识索引使用 因此在叙述上存在逻辑不通顺 跨度大等问题 希望理解 分享出来仅供大家学习翻阅 若有错误希望指出 感谢 面向对象 JavaScript中没有类的概念 我们可以把对象看作散列表 无非就是一
  • html中的checkbox不显示值,html checkbox的checked属性问题和value属性问题

    lt html xmlns http www w3 org 1999 xhtml gt lt head gt lt script type text JavaScript gt function onbutton document getE
  • 前端Img使用图片跨域问题是怎么引起的?该如何解决呢?

    在项目种遇到一个问题 图片在dom节点这种使用了 img 标签来加载可以正常显示 但是运用到style中没有经过标签的加载就会出现跨域的问题 怎么会引起这个问题呢 1 通过 img 加载的图片 浏览器默认情况下会将其缓存起来 2 当我们从
  • 为什么数据分析进行的预测不够成功

    行业专家有时感叹大规模分析和数据科学计划经常缺乏价值 虽然人们从许多努力中看到了其巨大的价值 但结果非常差的例子也屡见不鲜 专家认为 通常这些问题可以归结为一个基本的错误 也就是说 认为生成预测 预测或模拟就足够了 但事实却不是这样 预测是
  • go 打开文件句柄_Go中trace包的使用

    Go给我们提供了一个工具trace 可以在运行时启用trace 并获得程序执行情况的详细视图 应该怎么使用trace呢 一般有下面三种使用方式 运行go test的时候 带上 trace参数标记 go test trace trace ou