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

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

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

上图显示了部分trace快照。在这次垃圾收集过程中,三个P(总共12个P)专用于GC。你可以看到Goroutine 2450,1978和2696在这段时间里正在进行Mark Assist的工作,而不是执行应用程序。在Mark的最后,只有一个P专用于GC并最终执行STW(标记终止)工作。

垃圾收集完成后,除了你看到Goroutines下面有很多玫瑰色的线条之外,应用程序几乎恢复全力运行。

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

上图中那些玫瑰色线条代表Goroutine执行清理工作而非执行应用程序。这也是Goroutine试图分配新内存的时刻。

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

上图图显示了Sweep过程中Goroutines stack trace的一部分。调用runtime.mallocgc用于分配新内存。最终调用runtime.(*mcache).nextFree 执行清理。一旦所有可以回收的内存都回收完毕,就不再对nextFree进行调用。

刚刚描述的行为仅在垃圾收集启动并运行时发生。而GC百分比配置选项对于何时进行垃圾收集起着重要作用。

GC百分比

运行时中有GC Percentage的配置选项,默认情况下为100。此值表示在下一次垃圾收集必须启动之前可以分配多少新内存的比率。将GC百分比设置为100意味着,基于在垃圾收集完成后标记为活动的堆内存量,下次垃圾收集前,堆内存使用可以增加100%。

举个例子,假设一个集合在使用中有2MB的堆内存。

注意:使用Go时,本文中堆内存的图表不代表真实情况。Go中的堆内存会碎片化。这些图只是示意图。

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

上图显示了最后一次垃圾完成后正在使用中的堆内存是2MB。由于GC百分比设置为100%,因此下一次收集会在在增加2 MB堆内存时启动。

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

上图显示增加2MB堆内存。这时触发一次垃圾收集。可以为每次GC都生成GC trace,就可以查看到相关动作。

GC Trace

在运行任何Go应用程序时,可以通过使用环境变量GODEBUG和gctrace = 1选项生成GC trace。每次发生垃圾收集时,运行时都会将GC trace信息写入stderr。

  1. GODEBUG=gctrace=1 ./app 
  2. gc 1405 @6.068s 11%: 0.058+1.2+0.083 ms clock, 0.70+2.5/1.5/0+0.99 ms cpu, 7->11->6 MB, 10 MB goal, 12 P 
  3. gc 1406 @6.070s 11%: 0.051+1.8+0.076 ms clock, 0.61+2.0/2.5/0+0.91 ms cpu, 8->11->6 MB, 13 MB goal, 12 P 
  4. gc 1407 @6.073s 11%: 0.052+1.8+0.20 ms clock, 0.62+1.5/2.2/0+2.4 ms cpu, 8->14->8 MB, 13 MB goal, 12 P 

上面展示了如何使用GODEBUG变量生成GC trace。同时显示了正在运行的Go应用程序生成的3条trace信息。

下面对GC trace中的每个值的含义进行的分解。

  1. gc 1405 @6.068s 11%: 0.058+1.2+0.083 ms clock, 0.70+2.5/1.5/0+0.99 ms cpu, 7->11->6 MB, 10 MB goal, 12 P 
  2.  
  3. // General 
  4. gc 1404     : The 1404 GC run since the program started 
  5. @6.068s     : Six seconds since the program started 
  6. 11%         : Eleven percent of the available CPU so far has been spent in GC 
  7.  
  8. // Wall-Clock 
  9. 0.058ms     : STW        : Mark Start       - Write Barrier on 
  10. 1.2ms       : Concurrent : Marking 
  11. 0.083ms     : STW        : Mark Termination - Write Barrier off and clean up 
  12.  
  13. // CPU Time 
  14. 0.70ms      : STW        : Mark Start 
  15. 2.5ms       : Concurrent : Mark - Assist Time (GC performed in line with allocation) 
  16. 1.5ms       : Concurrent : Mark - Background GC time 
  17. 0ms         : Concurrent : Mark - Idle GC time 
  18. 0.99ms      : STW        : Mark Term 
  19.  
  20. // Memory 
  21. 7MB         : Heap memory in-use before the Marking started 
  22. 11MB        : Heap memory in-use after the Marking finished 
  23. 6MB         : Heap memory marked as live after the Marking finished 
  24. 10MB        : Collection goal for heap memory in-use after Marking finished 
  25.  
  26. // Threads 
  27. 12P         : Number of logical processors or threads used to run Goroutines 

(编辑:江门站长网)

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