上图显示了部分trace快照。在这次垃圾收集过程中,三个P(总共12个P)专用于GC。你可以看到Goroutine 2450,1978和2696在这段时间里正在进行Mark Assist的工作,而不是执行应用程序。在Mark的最后,只有一个P专用于GC并最终执行STW(标记终止)工作。
垃圾收集完成后,除了你看到Goroutines下面有很多玫瑰色的线条之外,应用程序几乎恢复全力运行。
上图中那些玫瑰色线条代表Goroutine执行清理工作而非执行应用程序。这也是Goroutine试图分配新内存的时刻。
上图图显示了Sweep过程中Goroutines stack trace的一部分。调用runtime.mallocgc用于分配新内存。最终调用runtime.(*mcache).nextFree 执行清理。一旦所有可以回收的内存都回收完毕,就不再对nextFree进行调用。
刚刚描述的行为仅在垃圾收集启动并运行时发生。而GC百分比配置选项对于何时进行垃圾收集起着重要作用。
GC百分比
运行时中有GC Percentage的配置选项,默认情况下为100。此值表示在下一次垃圾收集必须启动之前可以分配多少新内存的比率。将GC百分比设置为100意味着,基于在垃圾收集完成后标记为活动的堆内存量,下次垃圾收集前,堆内存使用可以增加100%。
举个例子,假设一个集合在使用中有2MB的堆内存。
注意:使用Go时,本文中堆内存的图表不代表真实情况。Go中的堆内存会碎片化。这些图只是示意图。
上图显示了最后一次垃圾完成后正在使用中的堆内存是2MB。由于GC百分比设置为100%,因此下一次收集会在在增加2 MB堆内存时启动。
上图显示增加2MB堆内存。这时触发一次垃圾收集。可以为每次GC都生成GC trace,就可以查看到相关动作。
GC Trace
在运行任何Go应用程序时,可以通过使用环境变量GODEBUG和gctrace = 1选项生成GC trace。每次发生垃圾收集时,运行时都会将GC trace信息写入stderr。
- GODEBUG=gctrace=1 ./app
- 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
- 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
- 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中的每个值的含义进行的分解。
- 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
-
- // General
- gc 1404 : The 1404 GC run since the program started
- @6.068s : Six seconds since the program started
- 11% : Eleven percent of the available CPU so far has been spent in GC
-
- // Wall-Clock
- 0.058ms : STW : Mark Start - Write Barrier on
- 1.2ms : Concurrent : Marking
- 0.083ms : STW : Mark Termination - Write Barrier off and clean up
-
- // CPU Time
- 0.70ms : STW : Mark Start
- 2.5ms : Concurrent : Mark - Assist Time (GC performed in line with allocation)
- 1.5ms : Concurrent : Mark - Background GC time
- 0ms : Concurrent : Mark - Idle GC time
- 0.99ms : STW : Mark Term
-
- // Memory
- 7MB : Heap memory in-use before the Marking started
- 11MB : Heap memory in-use after the Marking finished
- 6MB : Heap memory marked as live after the Marking finished
- 10MB : Collection goal for heap memory in-use after Marking finished
-
- // Threads
- 12P : Number of logical processors or threads used to run Goroutines
(编辑:ASP站长网)
|