Go GC:在 Go 1.5 解决延迟问题 已翻译 100%

oschina 投递于 2015/07/09 17:50 (共 6 段, 翻译完成于 07-17)
阅读 5453
收藏 32
Go
3
加载中

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 年左右,随着摩尔定理的终止,这个良性循环也结束了。

asdfsx
asdfsx
翻译于 2015/07/16 23:17
3

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

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

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

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

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

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

asdfsx
asdfsx
翻译于 2015/07/17 11:53
2

怎样使延迟具体化?

  • 纳秒: 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 能够让你在线程中嵌入另一个线程。以下的多层指针严重地导致了垃圾回收器的很多问题。

Summer姐姐
Summer姐姐
翻译于 2015/07/15 16:40
1

GC 基本知识

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

image

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

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

Summer姐姐
Summer姐姐
翻译于 2015/07/15 17:26
2

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

Summer姐姐
Summer姐姐
翻译于 2015/07/15 18:11
1

未来

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



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

问答

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

asdfsx
asdfsx
翻译于 2015/07/16 16:11
2
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(14)

y
yockie2018
真是服了,这么好的文章,不会翻译就不要误人,列举几个没法看的翻译:
“runtime written by GO” -> "执行 go 的运行时间"
"Leverages GO same as users" -> "使 go 和用户同步"
"spatial locality" -> "空间位置" (大哥大姐,过分了啊)
“Go enables you to embed structs within one another” -> "Go 能够让你在线程中嵌入另一个线程"
"Go 1.5, GC pauses are more than order of magnitude shorter." -> "在Go 1.5中,GC 暂停比以往的短数量级多" (完全相反的意思,应该是GC暂停时间缩短了几个数量级。)

后面没法再看了。。。
asdfsx
asdfsx

引用来自“asdfsx”的评论

中间那两段我想改,但不知道怎么弄

引用来自“Summer_秌焰”的评论

你把中间两段需要修改的地方 发给我 我可以改过来
录音声道的同步 ->使用管道进行同步 对象/锁定器的同步 -> 使用对象/锁进行同步 执行C的运行时间 -> 由C实现的运行时 其它的想到再说吧
Summer姐姐
Summer姐姐

引用来自“asdfsx”的评论

中间那两段我想改,但不知道怎么弄
你把中间两段需要修改的地方 发给我 我可以改过来
Z
ZXEOC

引用来自“君陌”的评论

tens of 翻译成数以万计?
Java能跑数以万计的线程。。
估计是看成tons of了吧
duchipore
duchipore
然而并没有什么卵用
asdfsx
asdfsx
中间那两段我想改,但不知道怎么弄
wei_193
wei_193
翻译有点.....
懶蟲
懶蟲
这是怎么翻译的?一键翻译?
君陌
君陌
tens of 翻译成数以万计?
Java能跑数以万计的线程。。
__JM_Joy__
__JM_Joy__
好!
返回顶部
顶部