百科问答小站 logo
百科问答小站 font logo



如何看待GO语言的新GC(TOC)? 第1页

  

user avatar   yuhengk 网友的相关建议: 
      

谨慎乐观。首先这不是一个全新GC, 而是原有GC上加的一个新优化路径。TOC要解决的问题或者背景假设是很经典的,用正常人的话来说就是:「程序执行中产生的大部分对象的生命周期都很短,而且都只在局部使用。」基于局部使用假设,首先可以做的是静态的逃逸分析,在编译期就指出很大一部分对象的生命周期,这个 Go 也已经做了,而且还在优化。至于不能在编译期确定生命周期的,在运行时的垃圾回收中很常见的做法就是分代 GC, 让年轻对象更快更容易回收,降低全局 GC 压力。

而 TOC 基于的假设是上面短生命周期假设的一个特化版本:

  1. 绝大部分事务(比如一个 HTTP 请求处理)都是短事务。
  2. 每个事务开一个新的 goroutine 来处理,处理完 goroutine 结束。
  3. 执行期间产生的大部分对象都只在goroutine内部使用。

那么,如果可以准确标记哪些对象是跨 goroutine 共享了,那在goroutine结束的时候把没有共享出去的全回收掉就可以了。实现一个准确及时回收内存还能用好多核还性能好的分代GC非常复杂,还要针对各种场景优化,我记得 golang-dev 邮件组讨论过要不要实现分代 GC, 不过看来结论是 TOC 了,TOC其实就是一个基于特化假设的特化简单实现,这很 gopher.

一个对象有没有跨goroutine共享出去(文档里的publish)是有传递关系的,你被一个published的对象引用了那你和所有你引用的对象也published了,如果我没看错,现在的设计是要在write barrier上递归标记这个状态的。我会担心这样下来是否会有一些场景的运行时开销比原来更大了。TOC 对它要优化的场景应该是能同时实现提高吞吐(降低运行时开销),降低停顿时间和节省内存占用的目标的,还能在多核环境高效扩展,而这个场景也确实是网络服务中的统治性场景。但还是要看有没有被严重劣化的场景,以及最后真实服务的综合效能。

这种运行时优化的东西,现在已经很难有一个超级聪明的想法然后秒杀所有前人成果了,都是针对实用场景优化,很多时候只要运行时数据摆在你面前,解决方法是显而易见的。我一直对 Go 的运行时优化持乐观态度,并不是因为有大牛操刀,而是因为他们可以从Google内部机群拿到巨量的运行时数据来支持设计决策和测试新想法。保持简单,看实际环境数据做优化,这个大方向是靠谱的。




  

相关话题

  为什么 Go 语言能在中国这么火? 
  是不是后置类型语言的函数一定要加关键字,不加关键字编译器识别不出吗? 
  为什么微软不出一门像 Go 或者 Rust 的跨平台系统级语言? 
  为什么 Go 语言如此不受待见? 
  同样是巨头的语言,为什么中国是 Go 最热的国家,而 C# 越来越少? 
  go语言,局部变量什么时候回收? 
  Go语言中如何检测一个channel已经被关闭了? 
  第三届 Gopher China 大会值得参加吗? 
  如何理解 Golang 中“不要通过共享内存来通信,而应该通过通信来共享内存”? 
  使用 Unix Domain Socket 连接 MySQL,查询速度和使用 127.0.0.1 连接差不多,使用 Go 测试,为什么? 

前一个讨论
星巴克(中国)是否存在问题?如有,怎么解决?
下一个讨论
有哪些小病不及时治疗,发展到最后难以挽救的病例?





© 2025-02-06 - tinynew.org. All Rights Reserved.
© 2025-02-06 - tinynew.org. 保留所有权利