如何优化golang gc

news2024/11/15 5:05:19

目录

一.理解GO GC机制

1.1GC的耗时

1.2堆大小对GC的影响

1.3GC算法

二 如何查看GC信息

2.1使用GODEBUG="gotrace=1"

2.2 go tool trace

2.3 debug.ReadGCStats

​编辑2.4 runtime.ReadMemStats

三 GC优化技巧 

2.1并发GC


一.理解GO GC机制

GO语言采用的是三色标记法垃圾回收算法,这种算法采用的是并发标记,扫描完成后再进行清除工作,这意味着性能上可能会付出一些代价。

1.1GC的耗时

在垃圾收集周期内,所有的goroutine必须停止运行以便垃圾回收器可以尽可能多地清除内存。GC会带来一些显著的延迟,大部分gc耗时都集中于标记阶段。越大的堆空间,GC的时间也越长。

1.2堆大小对GC的影响

每个程序都有一个堆大小,这个大小是通过runtime.GOMAXPROCS和runtime.GOGC这两个环境变量来控制的。runtime.GOGC默认是100,意味着当达到100%的可用内存时,GC将开始在程序运行期间自动执行垃圾回收。而runtime.GOMAXPROCS控制程序并发时最大的goroutine数量。

//todo举个例子

1.3GC算法

Go语言采用三色标记算法的主要优点是能够在很短的时间内清理整个堆,避免了没有必要的清理操作。三色标记算法具有最小停顿时间和实时清理堆的能力,但是,它需要非常高的内存扫描性能。这是由于算法需要对对象执行读取和写入操作。所以我们需要在内存使用量和最小停顿时间之间进行平衡。

//todo 三色标记法

二 如何查看GC信息

2.1使用GODEBUG="gotrace=1"

package main

func main() {
	//循环分配很大内存,触发GC
	for n := 1; n < 100; n++ {
		a := make([]byte, 1<<20)
		a = a
	}
}

 命令行使用 GODEBUG="gctrace=1"

字段解析: 

gc 2这是第2次gc。
@0.041s 这次gc的markTermination阶段完成后,距离runtime启动到现在的时间。
 1%

到目前为止,gc的标记工作(包括两次mark阶段的STW和并发标记)所用的CPU时间占总CPU的百分比

 0.053+0.95+0.004 ms clock,按顺序分成三部分
0.053表示mark阶段的STW时间(单P的);
0.95表示并发标记用的时间(所有P的);
0.004表示markTermination阶段的STW时间(单P的)。
0.21+0.093/0.35/0.60+0.018 ms cpu按顺序分成三部分
0.21表示整个进程在mark阶段STW停顿时间(0.013 * 8);

0.093/0.35/0.60有三块信息,0.093是mutator assists占用的时间,
0.35是dedicated mark workers+fractional mark worker占用的时间,
0.60是idle mark workers占用的时间。

0.018 ms表示整个进程在markTermination阶段STW停顿时间。
 3->3->0 MB,

按顺序分成三部分,
3表示开始mark阶段前的heap_live大小;

3表示开始markTermination阶段前的heap_live大小;
0表示被标记对象的大小。

4 MB goal, 0 MB stacks, 0 MB globals,

表示下一次触发GC的内存占用阀值是4MB,

4 P本次gc共有多少个P。

2.2 go tool trace

package main

import (
	"os"
	"runtime/trace"
)

func GoTrace() {
	f, _ := os.Create("trace.out")
	defer f.Close()
	trace.Start(f)
	defer trace.Stop()
	//循环分配很大内存,触发GC
	for n := 1; n < 100; n++ {
		a := make([]byte, 1<<20)
		a = a
	}

}

代码执行完成后可以看到会生成trace.out文案,使用 go tool trace命令查看trace文件

go tool trace -http 127.0.0.1:8080 trace.out

 

 

2.3 debug.ReadGCStats

package main

import "time"

func main() {
	go RunTimeDebugReadGc()
	//循环分配很大内存,触发GC
	for n := 1; n < 100; n++ {
		a := make([]byte, 1<<20)
		a = a
	}
	//方便观察 sleep 10s
	time.Sleep(10 * time.Second)
}

func RunTimeDebugReadGc() {
	//每秒触发一次
	tracker := time.NewTicker(1 * time.Second)
	gcStat := debug.GCStats{}
	for {
		select {
		case <-tracker.C:
			debug.ReadGCStats(&gcStat)
			fmt.Println(gcStat)
		}
	}
}



2.4 runtime.ReadMemStats

func RunTimeDebugReadMem() {
	//每秒触发一次gc
	tracker := time.NewTicker(1 * time.Second)
	gcStat := runtime.MemStats{}
	for {
		select {
		case <-tracker.C:
			runtime.ReadMemStats(&gcStat)
			fmt.Println(gcStat)
		}
	}
}

三 GC优化技巧 

3.1并发GC

并发GC是指GC开始之前,应用程序仍然可以继续执行。 Go语言的GC只有在程序不能继续执行时才运行。同样,因为垃圾回收时程序不工作,因此并发垃圾回收可以大大减少程序停止运行的时间。

3.2非对齐内存分配

内存对接分配可以参考

非对齐内存分配是指在堆上申请非对齐内存块。这是一种减少内存碎片的方法。内存碎片是指多个内存块之间的间隙。通常,当使用堆管理器来管理内存时,垃圾回收时需要在堆中移动和调整不同的内存块,这会导致大量的内存拷贝。如果能够减少碎片,GC的效率就会更高。

3.3手动触发GC

手动触发GC是指在程序运行期间显式调用runtime.GC函数。虽然这不是最激进的解决方案,但它可以有效地减少GC的延迟。

3.4调整GOGC

在程序高峰期跑GC可能会对性能造成严重影响。可以适当调整runtime.GOGC的值来减少GC的频率,根据应用程序的工作负载和内存使用模式,应适当调整该变量。

3.4避免使用GC

通过避免在程序中使用不必要的动态内存分配和释放,可以减少GC的频率和延迟。此外,还可以使用对象池来重新使用不再使用的对象,从而不会立即释放内存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/510299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习网络安全的拦路虎!你遇到几个?

很多零基础的同学想要学习网络安全&#xff0c;前期会各种寻找学习资料。最后发现资料一大堆&#xff0c;但无从下手&#xff0c;于是千辛万苦收集的资料就去收藏夹吃灰了。开始学习的小伙伴们通常也会越学越迷茫&#xff0c;毕竟资料并不是完整的&#xff0c;而是东拼西凑出来…

Docker时区问题

背景 当前docker容器技术应用越来越广泛&#xff0c;但在启动容器后&#xff0c;容器内部的时间并不是东八区 Docker的基础镜像设置大多是UTC&#xff0c;也就是标准的UTC 时间&#xff0c;所以要简单的调整一下&#xff0c;变成中国标准时间CST(China Standard Time UTC8:0…

OpenCL编程指南-1.2OpenCL图形API

OpenCL与图形 OpenCL的出现是对GPCPU编程的一个响应。人们用GPU处理图形&#xff0c;并且开始使用GPU完成工作中的非图形部分。基于这种趋势&#xff0c;异构计算&#xff08;已经存在很长时间&#xff09;与图形发生冲突&#xff0c;因此迫切需要一个行业标准。 OpenCL一直与…

使用Onenote进行钓鱼攻击事件分析

以其中遇到的一个案例为例子进行展开分析: 1、使用钓鱼邮件文案.one文件附件 From: Bank Complaints <bankcomplaintshkmagov.com> Sent: Thursday, March 2, 2023 11:00 AMTo: Miles Mok XXXXSubject: [External Mail] xxxx Industry Development Survey Dear XXXX Lt…

SpringBoot+Canal+RabbitMQ实战

1. Canal简介 https://github.com/alibaba/canal 1.1 Canal工作原理 MySQL主备复制原理 MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events&#xff0c;可以通过 show binlog events 进行查看)MySQL slave 将 master 的 b…

中断-NVIC与EXTI外设详解(超全面)

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转STM32 &#x1f4ac;推荐一…

档案馆对于档案室档案库房内温度和湿度的控制要求

编辑搜图 请点击输入图片描述&#xff08;最多18字&#xff09; 01 纸质档案库的温湿度要求 用房名称温度&#xff08;℃&#xff09;相对湿度&#xff08;%&#xff09;纸质档案库14~2445~60 02 特殊档案库的温湿度要求 用房名称温度&#xff08;℃&#xff09;相对湿度&am…

Golang中的运算符

目录 运算符 算术运算符 代码案例&#xff1a; 关系运算符 代码案例&#xff1a; 逻辑运算符 代码案例&#xff1a; 位运算符 代码案例&#xff1a; 赋值运算符 代码案例&#xff1a; 其他运算符 运算符 算术运算符 Go语言中的算术运算符包括加、减、乘、除和取模…

【深入理解redis】数据结构

文章目录 动态字符串SDS字符串编码类型 intsetDictZipListZipList的连锁更新问题 QuickListSkipListRedisObjectStringListSet结构ZSETHash Redis 共有 5 种基本数据结构&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;…

2023进销存财务软件哪个好?哪些适合中小商户使用?

对于开店的老板来说&#xff0c;门店的财务管理一直都是比较头疼的一件事&#xff0c;销售业绩人工统计困难&#xff0c;记账对账效率低且容易出错。 使用进销存财务软件可以有效的帮助门店解决财务管理问题&#xff0c;但市面上这么多进销存财务软件&#xff0c;哪些性价比较高…

Android编译优化之混淆配置

Android编译优化之混淆配置 背景 为了使用java8及后续java新版本的特性&#xff0c;Google增加了一步编译过程—脱糖&#xff08;desugaring&#xff09;&#xff0c;但这一步会导致更长的编译时间&#xff0c;这也是为什么Google会推出D8和R8编译器来优化编译速度。 什么是脱…

【C语言】扫雷游戏

这里写目录标题 前言1.初始化棋盘2.展示棋盘3.布置雷4.开始扫雷4.1判断输赢4.2扫雷时连续性展开4.3展示玩法 5.整体代码展示5.1 game.h头文件展示5.2 game.c源文件展示5.3 text.c源文件展示 所属专栏&#xff1a;C语言 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyan…

了解 XML结构(一)

文章目录 1 XML定义2 了解XML结构3 XML节点类型4 加载读取XML5 小结 1 XML定义 XML是一种可扩展标记语言&#xff08;Extensible Markup Language, XML&#xff09;,可以用来标记数据&#xff0c;定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。 …

数据治理是一个部门的工作还是全业务体系的工作?_光点科技

随着互联网时代的到来&#xff0c;数据已成为企业生产和经营的重要资源。但是&#xff0c;随着数据量的不断增加和数据形态的多样化&#xff0c;如何管理和利用数据也成为了企业面临的一个重要问题。在这个过程中&#xff0c;数据治理成为了一个备受关注的话题。 那么&#xff…

ChatGPT1论文解读《Improving Language Understanding by Generative Pre-Training》

论文总结 以下是我阅读完整篇论文做的个人总结&#xff0c;基本包含了chatGPT1设计的完整框架思路&#xff0c;可以仅看【论文总结】章节。 在GPT1实现的核心架构中&#xff0c;包含两个阶段。 第一阶段 在第一阶段基于一个包含7000本书籍内容的海量未标注文本数据集进行无…

IP-Guard能否支持通过审批后才能发送邮件?

支持,但目前暂时只支持带有附件的邮件通过申请审批或者自我备案放开策略控制发送出去。 使用方式: 1、申请审批:设置了禁止发送邮件的邮件控制策略后,在申请权限-发送邮件中,设置允许发送,设置相关审批流程,管理员审批完成后即可发送。 -申请权限-审批流程 2、自我备案:…

SSM框架学习-注解开发第三方bean管理

1. 复习xml配置文件管理第三方bean 在Spring中&#xff0c;可以使用依赖注入&#xff08;Dependency Injection&#xff09;来管理和使用第三方Bean。Spring提供了多种方式来进行依赖注入&#xff0c;比如构造函数注入、Setter方法注入、字段注入等。下面以Setter方法注入为例&…

pycharm 常用插件,常用插件推荐

1. Key Promoter X 如果让我给新手推荐一个 PyCharm 必装插件&#xff0c;那一定是 Key Promoter X 。 它就相当于一个快捷键管理大师&#xff0c;它时刻地在&#xff1a; 教导你&#xff0c;当下你的这个操作&#xff0c;应该使用哪个快捷操作来提高效率&#xff1f;提醒你…

Scala学习(二)

文章目录 1.Scala的运算符1.1 Scala中的equals和 2.流程控制2.1 if2.2 Scala中的三目运算符2.3 for循环 3.循环中断 1.Scala的运算符 1.1 Scala中的equals和 回顾Java中的运算符 equals和,equals比较的为值&#xff0c; 比较的为地址 String a1new String("hi");…

【数据结构】线性表——带头双向循环链表

文章目录 带头双向循环链表带头双向循环链表主体结构带头双向循环链表操作函数介绍带头双向循环链表操作函数实现带头双向循环链表的初始化函数&#xff1a;打印函数带头双向循环链表插入函数&#xff1a;指定结点后插入和查找函数头插尾插 带头双向循环链表删除函数指定结点删…