使用 TB 级 RAM 的 go 1.5 gc 有多快?
How fast is the go 1.5 gc with terabytes of RAM?
Java 无法使用数 TB 的 RAM,因为 GC 暂停时间太长(分钟)。随着最近对 Go GC 的更新,我想知道它的 GC 暂停是否足够短以用于大量 RAM,例如几 TB。
有这方面的基准吗?我们现在可以使用具有这么多 RAM 的垃圾收集语言吗?
tl;dr:
- 您现在无法在单个 Go 进程中使用 TB 的 RAM。 Linux 上的最大值为 512 GB,而我见过的大多数测试是 240 GB。
- 对于当前的后台 GC,GC workload 往往比 GC pauses.
更重要
- 您可以将 GC 工作负载理解为 指针 * 分配率 / 备用 RAM。在使用大量 RAM 的应用程序中,只有那些指针很少或分配很少的应用程序才会有较低的 GC 工作量。
我同意 inf 的评论,即大堆值得向其他人询问(或测试)。 JimB 指出 Go 堆目前有 512 GB 的硬限制,18 240 GB 是我测试过的最大。
关于大堆我们知道的一些事情,来自the design document and the GopherCon 2015 slides:
- 1.5 收集器的目标不是减少 GC work,只是通过在后台工作来减少 pauses。
- 当 GC 扫描堆栈上和全局变量中的指针时,您的代码暂停。
1.5 GC 在具有大约 18GB 堆的 GC 基准测试中有一个短暂的停顿,如 this graph from the GopherCon talk 底部最右边的黄点所示:
伙计们 运行 几个最初有大约 300 毫秒暂停的生产应用程序报告下降到 ~4ms and ~20ms. Another app reported their 95th percentile GC time went from 279ms to ~10ms。
Go 1.6 added polish and pushed some of the remaining work to the background. As a result, tests with heaps up to a bit over 200GB still saw a max pause time of 20ms, as shown in a slide in an early 2016 State of Go talk:
暂停时间低于 1.5 毫秒的同一应用程序有 3-4ms pauses under 1.6, with about an 8GB heap and 150M allocations/minute。
使用 Go 进行聊天服务的 Twitch 报告说 by Go 1.7 pause times had been reduced to 1ms with lots of running goroutines。
1.8 took stack scanning out of the stop-the-world phase, bringing most pauses well under 1ms, even on large heaps. Early numbers look good。偶尔,应用程序仍然具有使 goroutine 难以暂停的代码模式,有效地延长了所有其他线程的暂停时间,但通常可以公平地说 GC 的 后台工作 现在通常比GC 暂停。
关于垃圾收集的一些一般观察,不特定于 Go:
- 收集的频率 取决于您愿意多快用完您愿意提供给进程的 RAM。
- 每个集合的工作量部分取决于正在使用的指针数量。
(包括 the pointers within slices, interface values, strings, etc.)
换句话说,访问大量内存的应用程序如果只有几个指针(例如,它处理相对较少的大 []byte
缓冲区)可能仍然没有 GC 问题,并且如果分配率很低(例如,因为您应用 sync.Pool
以在您最快速地咀嚼 RAM 的任何地方重用内存)。
因此,如果您正在寻找涉及数百 GB 堆的东西,而这些堆自然不是 GC 友好的,我建议您考虑
- 用 C 等编写
- 将庞大的数据移出对象图。例如,如果您需要比 DB
更多的缓存,则可以在 bolt
, put it in an outside DB service, or use something like groupcache
或 memcache 等嵌入式数据库中管理数据
- 运行 一组小堆进程而不是一个大进程
- 只需仔细制作原型、测试和优化以避免内存问题。
新的 Java ZGC 垃圾收集器现在可以使用 16 TB 内存并在 10 毫秒内完成垃圾收集。
Java 无法使用数 TB 的 RAM,因为 GC 暂停时间太长(分钟)。随着最近对 Go GC 的更新,我想知道它的 GC 暂停是否足够短以用于大量 RAM,例如几 TB。
有这方面的基准吗?我们现在可以使用具有这么多 RAM 的垃圾收集语言吗?
tl;dr:
- 您现在无法在单个 Go 进程中使用 TB 的 RAM。 Linux 上的最大值为 512 GB,而我见过的大多数测试是 240 GB。
- 对于当前的后台 GC,GC workload 往往比 GC pauses. 更重要
- 您可以将 GC 工作负载理解为 指针 * 分配率 / 备用 RAM。在使用大量 RAM 的应用程序中,只有那些指针很少或分配很少的应用程序才会有较低的 GC 工作量。
我同意 inf 的评论,即大堆值得向其他人询问(或测试)。 JimB 指出 Go 堆目前有 512 GB 的硬限制,18 240 GB 是我测试过的最大。
关于大堆我们知道的一些事情,来自the design document and the GopherCon 2015 slides:
- 1.5 收集器的目标不是减少 GC work,只是通过在后台工作来减少 pauses。
- 当 GC 扫描堆栈上和全局变量中的指针时,您的代码暂停。
1.5 GC 在具有大约 18GB 堆的 GC 基准测试中有一个短暂的停顿,如 this graph from the GopherCon talk 底部最右边的黄点所示:
伙计们 运行 几个最初有大约 300 毫秒暂停的生产应用程序报告下降到 ~4ms and ~20ms. Another app reported their 95th percentile GC time went from 279ms to ~10ms。
Go 1.6 added polish and pushed some of the remaining work to the background. As a result, tests with heaps up to a bit over 200GB still saw a max pause time of 20ms, as shown in a slide in an early 2016 State of Go talk:
暂停时间低于 1.5 毫秒的同一应用程序有 3-4ms pauses under 1.6, with about an 8GB heap and 150M allocations/minute。
使用 Go 进行聊天服务的 Twitch 报告说 by Go 1.7 pause times had been reduced to 1ms with lots of running goroutines。
1.8 took stack scanning out of the stop-the-world phase, bringing most pauses well under 1ms, even on large heaps. Early numbers look good。偶尔,应用程序仍然具有使 goroutine 难以暂停的代码模式,有效地延长了所有其他线程的暂停时间,但通常可以公平地说 GC 的 后台工作 现在通常比GC 暂停。
关于垃圾收集的一些一般观察,不特定于 Go:
- 收集的频率 取决于您愿意多快用完您愿意提供给进程的 RAM。
- 每个集合的工作量部分取决于正在使用的指针数量。 (包括 the pointers within slices, interface values, strings, etc.)
换句话说,访问大量内存的应用程序如果只有几个指针(例如,它处理相对较少的大 []byte
缓冲区)可能仍然没有 GC 问题,并且如果分配率很低(例如,因为您应用 sync.Pool
以在您最快速地咀嚼 RAM 的任何地方重用内存)。
因此,如果您正在寻找涉及数百 GB 堆的东西,而这些堆自然不是 GC 友好的,我建议您考虑
- 用 C 等编写
- 将庞大的数据移出对象图。例如,如果您需要比 DB 更多的缓存,则可以在
- 运行 一组小堆进程而不是一个大进程
- 只需仔细制作原型、测试和优化以避免内存问题。
bolt
, put it in an outside DB service, or use something like groupcache
或 memcache 等嵌入式数据库中管理数据
新的 Java ZGC 垃圾收集器现在可以使用 16 TB 内存并在 10 毫秒内完成垃圾收集。