<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/RLH/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/RLH">@RLH</a> and I have been discussing this problem for the past week. This issue is to track our thoughts.</p>
<p dir="auto">The current GC pacer is conservative about scheduling mutator assists and this leads to a cycle where we over-assist (use too much CPU for GC) and under-shoot the heap goal.</p>
<p dir="auto">Specifically, GC currently assumes it may have to scan the entire live heap before the live heap size reaches the heap goal. It sets the assist ratio accordingly. If the reachable heap is growing, this conservative assumption is necessary to prevent the mutator from outpacing the garbage collector and spiraling the heap size up. However, in steady state (where the reachable heap size is roughly the same as it was the last GC cycle), this means we'll finish garbage collection when we're less than 100/(GOGC+100) of the way from the trigger to the goal (1/2 way for GOGC=100; 1/4 way for GOGC=300; etc).</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/2688315/14031881/762a8fd4-f1e5-11e5-990f-b35e165ec558.png"><img src="https://cloud.githubusercontent.com/assets/2688315/14031881/762a8fd4-f1e5-11e5-990f-b35e165ec558.png" alt="overassist" style="max-width: 100%;"></a></p>
<p dir="auto">You might think the trigger controller would adapt by setting the GC trigger lower in response to the over-utilization, but in fact, this drives the trigger controller into a state of persistent CPU over-utilization and heap under-shoot. Currently, the trigger controller will leave the trigger where it is if we're anywhere on the white edge between CPU utilization and heap over-shoot shown below:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://cloud.githubusercontent.com/assets/2688315/14031986/229bc756-f1e6-11e5-832e-76109cbe5f04.png"><img src="https://cloud.githubusercontent.com/assets/2688315/14031986/229bc756-f1e6-11e5-832e-76109cbe5f04.png" alt="trigger" style="max-width: 100%;"></a></p>
<p dir="auto">The under-shoot caused by the over-assist forces the trigger controller to the left of the ideal point on this curve. Since this persists, we eventually settle well to the left of the ideal, repeatedly setting the trigger too close to the goal, which leads to the next cycle setting a high assist ratio and again finishing early.</p>
<p dir="auto">This is particularly visible in applications with a high allocation rate and/or high GOGC.</p>
<p dir="auto">by <strong>dop251</strong>:</p>
<pre class="notranslate">What steps will reproduce the problem?

1. Create a package with the following code:

package bug

type S struct {}

func (s *S) test() {
    goto end
end:
    return
}

2. Create another package that imports the first one:

package importbug

import (
    _ "bug"
)

3. Run 'go install' on that package

What is the expected output?

none

What do you see instead?

./bug.go:4: syntax error: unexpected &lt;

Which compiler are you using (5g, 6g, 8g, gccgo)?


Which operating system are you using?

Linux/amd64

Which version are you using?  (run 'go version')

1.2

Please provide any additional information below.</pre>