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

来源:开源中国社区 作者:oschian
  

Richard L. Hudson (Rick) 是内存管理方面的专家,发明了 Train, Sapphire(http://people.cs.umass.edu/~moss/papers/jgrande-2001-sapphire.pdf), 和 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

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

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

Go GC
 

Go GC 的算法是使用写屏障和短时间暂停的组合。下面是它的执行过程:

image

以下是 GC 算法在 Go 1.4 运行的情况:

image

以下是在 Go1.5 的情况:

image

注意回收器的短时间暂停。 在GC的并发期间,GC占据了25%的CPU.

以下是基准测试程序数值:

image

在Go的早期版本中,GC暂停一般比较长久, 它们随着堆的增长而增长。 在Go 1.5中,GC 暂停比以往的短数量级多。

放大时,在堆内存与 GC 暂停间是有一点正相关的。但是它们知道问题在哪里,并且将会在 Go1.6 中处理掉。

image

新的 GC 算法有轻微的吞吐量处罚,当堆内存增长时处罚收缩。

image

未来
 

告诉大家,自从  Go 有了低延迟GC,GC 已经不再是问题。未来,开发团队计划让 GC 变得延迟更低、吞吐量更高、更有预见性。他们会很好的平衡这些需求。Go 1.6 的开发工作,将由用例和反馈来驱动,所以大家有什么需求的话,请让他们知道。


 

新的低延时gggggggggggg GC 将使 Go 在更多方面替代手动内存管理语言,比如C。 

问答

问:有堆压缩的计划吗?
答:我们已经在计划中接纳了这项技术,它过去在 C 语言社区工作得很好。当在同一片内存里,存放同样大小对象时,这项技术可以避免产生大量碎片。

转自 http://www.oschina.net/translate/go-gc-solving-the-latency-problem-in-go-1-5


时间:2015-07-18 09:26 来源:开源中国社区 作者:oschian 原文链接

好文,顶一下
(0)
0%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量