加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

关于Golang GC的一些误解,真的比Java算法更领先吗?

发布时间:2019-08-13 20:44:43 所属栏目:优化 来源:William Kennedy
导读:首先强调下本文的起因是在高可用架构后花园群的一次聊天,大家在争论Golang的GC到底是类似Java的ZGC还是类似Java的CMS GC。我个人的看法是Golang的GC是类似于Java的CMS GC,官方的mgc的注释这么说的: //TheGCrunsconcurrentlywithmutatorthreads,istypeac

在垃圾收集器开始收集之前,它会计算预期完成垃圾收集的时间。一旦垃圾收集器开始运行,会影响正在运行的应用程序,造成延迟,拖慢用程序。每次收集都会增加应用程序的整体延迟。降低收集器的启动频率并非提高性能的方法。

可以将GC百分比值更改为大于100的值。这将增加在下一次收集启动之前可以分配的堆内存量。也导致垃圾收集时间更长。

关于Golang GC的一些误解,真的比Java算法更领先吗?

上图显示了更改GC百分比如何允许分配的堆内存。 可以直观地了解使用更多对内存如何降低垃圾收集的速度。

降低收集器的启动频率无法帮助垃圾收集器更快完成收集工作。降低频率会导致垃圾收集器在收集期间完成更多的工作(译者注:因为分配了更多的内存)。 可以通过减少新分配对象数量来帮助垃圾收集器更快完成收集工作。

注意:这个做法同时可以用尽可能小的堆来实现所需的吞吐量。 在云环境中运行时,最小化堆内存等资源的使用非常重要。

关于Golang GC的一些误解,真的比Java算法更领先吗?

上图显示了关于正在运行的应用程序的一些统计信息。蓝色版本显示的是没有优化的应用程序的统计信息。绿色版本是在去掉4.48GB的非生产性内存分配后的统计数据。

查看两个版本的平均收集速度(2.08ms vs 1.96ms),都约为2.0毫秒。这两个版本之间的根本变化在于每次垃圾收集时候的吞吐量。从3.98提高到了7.13个请求。吞吐量增加79.1%。垃圾收集的时间并没有随着内存分配的减少而减慢,而是保持不变。性能提升来自于每次垃圾收集期间,其他go routine可以完成更多工作。

调整垃圾收集的起博速度以推迟延迟成本并非提高应用程序性能的方式。

收集器延迟成本

每次垃圾收集会造成两种类型的延迟。 首先是窃取CPU容量。 这种被盗CPU容量的影响意味着应用程序在垃圾收集过程中没有全速运行。应用程序Goroutines现在与垃圾收集器的Goroutines共享P或完成Mark Assist。

关于Golang GC的一些误解,真的比Java算法更领先吗?

上图显示了应用程序使用75%的CPU工作。 这是因为收集器本身就有专用的P1。

关于Golang GC的一些误解,真的比Java算法更领先吗?

上图显示了应用程序(通常只有几微秒)只能将其CPU容量的一半用于应用程序工作。 因为P3上的goroutine正在执行Mark Assist,而且垃圾收集器已经将P1占为己有。

第二种延迟是收集期间发生的STW延迟。 STW期间没有应用程序Goroutines执行任何应用程序。 该应用程序基本上已停止。

关于Golang GC的一些误解,真的比Java算法更领先吗?

上图显示了所有Goroutines都停止的STW延迟。 每次垃圾收集都会发生两次。 如果应用程序正常运行,则垃圾收集器能够将大部分垃圾收集的总STW时间保持在100微秒或以下。

现在了解了垃圾收集器的不同阶段,内存的大小,调整的工作方式以及垃圾收集器对正在运行的应用程序造成的不同延迟。 有了这些知识,最终可以回答如何调优的问题。

调优

减少堆内存的压力是最好的优化方式。 压力可以定义为应用程序在给定时间内分配堆内存的速度。 当堆内存压力减小时,垃圾收集器造成的影响会减少。减少GC延迟的方法是从应用程序中识别并去掉不必要的内存分配。

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读