Go GC:在 Go 1.5 解决延迟问题

简介:

Richard L. Hudson (Rick) 是内存管理方面的专家,发明了 Train, Sapphire, 和 Mississippi Delta 等算法,其中 GC stack maps 算法使静态类型语言(比如:Java,C#, Go)的垃圾收集成为可能。他发表了很多关于语言运行时内存管理、并发、并行、内存模型、事务内存的文章。Rick 是 Google Go 团队的一员,并负责 Go 的 GC 和运行时的问题。

在经济上,有个词叫良性循环 —— 不同的事务之间互相促进。在过去的技术界,软硬件的开发也曾近有类似的良性循环。随着 CPU 硬件的升级,运行更快的软件被开发出来,这又促使 CPU 的速度和计算能力进一步的提升。在 2004 年左右,随着摩尔定理的终止,这个良性循环也结束了。

现在,更多的晶体管不会带来更快的速度。更多的晶体管意味着更多的核,但是软件还不能完全发挥多核的性能。因为今天的软件不能让多核全部跑起来,那些搞硬件的就不会在 CPU 中集成更多的核。循环被破坏了。

Go 的一个长期目标就是通过提供更多的并行、并发程序来重启这个循环。短期内,我们要做的是提高 Go 的使用率。目前 Go 运行时遇到的最大的问题是 GC 暂停时间太长。

当他的团队开始接手这个问题,他像其它工程师一样开玩笑说,他们最开始的反应不是为了解决这个问题,而是这样解决问题:

添加一个监控器,不停的跟踪计算机和 GC

当 GC、网络延时、等怪情况发生时,发出一个网络等待标志

但是 Russ Cox 否决了这些想法,所以他们决定挽起袖子好好的努力提升 Go 的 GC。他们开发的算法会牺牲程序的运行能力来减少 GC 延迟。也就是说为了实现更低的 GC 延迟,Go 程序会比以前跑的稍微慢一点。

怎样使延迟具体化?

纳秒: Grace Hopper 用距离类推时间。 一纳秒等于11.8英寸。

微秒: 光在真空中走1英里所用的时间就是5.4微秒。

毫秒

1:从 SSD 中连续的读取1MB内存

20:从副产品磁盘中读取1MB内存

50:感性的因果关系 (眼睛/光标 响应的临界点).

50+: 各种各样的网络延迟

300: 眨眼

所以我们能够在1毫秒的时间内做多少 GC?

Java GC vs. Go GC
image

Go:

成千上万的 goroutines

使用管道进行同步

执行 go 的运行时间,使 go 和用户同步

空间位置的控制 (可以嵌入结构,内部指针 (&foo.field))

Java:

数十个Java线程

使用对象/锁的同步

由C实现的运行时间

对象连接指针

最大的区别在于空间位置的问题。 在Java中, 一切都是指针,然而 Go 能够让你在线程中嵌入另一个线程。以下的多层指针严重地导致了垃圾回收器的很多问题。

GC 基本知识
下面是一个关于垃圾回收器的快速入门,它们通常涉及2个阶段。

image

扫描阶段:在堆中确定哪些东西是可获得的。 这涉及到堆、缓存器、全局变量的指针的开始,到这些指针进入到栈。

标记阶段:绕指针一圈。在你读取的程序中尽可能标记出对象。从 GC 的角度来说, 当标记的段落并发的时候,指针还没有改变,要终止它是最简单的。GC 真正地并发是非常难的,因为指针是不断改变的。 程序使用被称为执行障碍的一些东西去关联 GC,但是它并不会回收对象。 在实践中, 写屏障会比暂停回收器昂贵。

文章转载自 开源中国社区 [http://www.oschina.net]

相关文章
|
算法 Java Go
Go语言GC:吞吐量和延迟的博弈
Go语言GC:吞吐量和延迟的博弈
208 0
|
2月前
|
人工智能 监控 算法
Go语言GC:三色标记法工程启示
本文深入探讨了Go语言中垃圾回收(GC)机制的性能影响及优化策略。首先分析了GC可能成为性能瓶颈的原因,如延迟敏感场景下的服务响应时间突增问题。接着介绍了三色标记法的核心概念与工作流程,以及并发GC面临的挑战和写屏障的作用。文章还详细讲解了Go GC的完整流程,并提供了多种工程实践启示,包括减少分配频率、预分配内存、避免过度使用指针、合理设置GOGC参数以及监控GC指标等优化方法。最后总结了GC优化的核心策略,帮助开发者构建更高效、可靠的Go应用。
|
存储 算法 Go
go语言中的延迟执行函数
【5月更文挑战第13天】`defer`是Go语言中用于延迟执行函数的关键字,尤其适用于资源管理,如文件关闭和锁的释放。它在函数返回前按照LIFO顺序执行,确保资源在任何返回路径下都能正确释放。`defer`可以拦截`panic`并在函数返回前执行,但无法阻止某些致命的`panic`。此外,`defer`可用于修改返回值、输出调试信息和还原变量值。尽管在某些场景下可能影响性能,但Go的优化使得其在多数情况下性能表现良好,特别是在资源清理方面。在Go 1.20及以后的版本,`defer`的性能已显著提升,尤其是在高计算量的场景下。
311 2
|
11月前
|
存储 Java 关系型数据库
听说过对 Go map 做 GC 吗?
听说过对 Go map 做 GC 吗?
|
11月前
|
存储 Go 调度
go-zero 如何应对海量定时/延迟任务?
go-zero 如何应对海量定时/延迟任务?
|
11月前
|
存储 设计模式 Java
Go - 使用 sync.Pool 来减少 GC 压力
Go - 使用 sync.Pool 来减少 GC 压力
97 0
go的函数定义、递归、延迟、匿名、高阶、闭包
go的函数定义、递归、延迟、匿名、高阶、闭包
|
Java Go 区块链
【Go语言专栏】Go语言中的延迟执行与defer语句
【4月更文挑战第30天】Go语言的延迟执行与defer语句用于资源释放和错误处理。defer通过关键字定义,函数返回时执行,顺序与定义相反。参数在定义时求值。应用包括资源释放、错误处理、成对操作和函数包装,是Go编程的关键特性。
104 0
|
存储 算法 Java
Go语言GC(垃圾回收)的工作原理
【2月更文挑战第23天】
252 0
|
算法 Java Go
Go语言GC:详解GC的五个阶段
【2月更文挑战第20天】
339 0