Go语言的垃圾回收方式与其他语言相比有何不同?

21

我对Go编程语言不是很了解,但我看到一些说法称Go具有无延迟垃圾回收功能,且比其他垃圾回收器(如JVM垃圾回收器)更好。我已经为JVM开发应用程序,并知道JVM垃圾回收器不是无延迟的(特别是在大内存使用情况下)。

我想知道,在Go中的垃圾回收方法与其他方法之间的区别是什么,这使其无延迟?

谢谢。


7
在Java游戏中,我从不允许垃圾回收器随意运行,直到达到适当的游戏时间点(例如暂停菜单)。为了实现这一点,我总是会有一种管理类,它保持对所有已创建对象的引用,并在达到暂停菜单或关卡结束时释放它们。 - Jon Taylor
@SaeedZarinfam 对于性能而言,垃圾收集器严重影响帧率,而且完全是不可预测的。没有办法让它在特定时间收集垃圾,除非保持所有资源并仅在安全时释放。 - Jon Taylor
1
@所有人,我已经完全编辑了这个问题,请投票以重新开放此问题,如果你同意的话。 - Saeed Zarinfam
重新打开... Golang如何实现无延迟GC? - Aaron Greenlee
@JonTaylor 这样做会真的防止GC运行吗?JVM如何知道不要将所有对象移动到类似于.NET的Gen2集合的扩展(长寿命)对象池中? - jocull
显示剩余2条评论
1个回答

22

Go语言没有完全消除延迟的垃圾回收。如果您能指出这些声明的位置,我会尝试进行更正。

我们认为Go相比Java有一个优势,那就是它可以让您更好地控制内存布局。例如,一个简单的2D图形包可能会定义:

type Rect struct {
    Min Point
    Max Point
}

type Point struct {
    X int
    Y int
}
在Go语言中,一个Rect只是内存中连续的四个整数。即使你将&r.Max传递给期望*Point的函数,那也只是指针进入了Rect变量r的中间部分。
在Java中,相应的表达式是创建Rect和Point类,这种情况下Rect中的Min和Max字段将是指向单独分配对象的指针。这需要更多分配的对象,占用更多内存,并使垃圾收集器需要跟踪和处理更多的对象。另一方面,它避免了需要创建指向对象中间的指针。
与Java相比,Go语言为程序员提供了更多的内存布局控制,你可以利用这个控制来减少垃圾收集器的负载。这在具有大量数据的程序中非常重要。控制内存布局也可能对从硬件中提取性能(由于缓存效果等)很重要,但这与原始问题无关。
当前Go发行版中的垃圾收集器是合理的,但绝不是最先进的。我们计划在未来一两年内投入更多精力进行改进。明确地说,Go的垃圾收集器肯定不如现代Java垃圾收集器好,但我们认为,在Go中编写不需要太多垃圾收集的程序更容易,因此,总体效果仍然是在等效的Java程序中垃圾收集不是那么重要。

1
我认为这更与Java语言相关,而不是JVM本身...Scala作为一种JVM语言,具有执行类似操作的值类 http://docs.scala-lang.org/overviews/core/value-classes.html我希望有更多资源比较JVM和Go gc,两者都非常有趣,我感觉它们都被很多谣言和误解所包围... - clagccs
1
@SaeedZarinfam,您可能误读了它。我在那里没有看到“无延迟垃圾回收”的声明(也没在快速搜索其历史记录中找到)。它只是说:“[…]我们有信心能够实现它,并且没有显著的延迟”(强调添加)。这段话以前紧接着一个关于当前实现的括号注释(该注释已被移动到自己的段落中)。对我来说,“没有显著的延迟”!=“无延迟”,它还涉及到未来的改进。 - Dave C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接