Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: should there be a minimum heap size to trigger GC? #9067

Closed
rsc opened this issue Nov 7, 2014 · 5 comments
Closed

runtime: should there be a minimum heap size to trigger GC? #9067

rsc opened this issue Nov 7, 2014 · 5 comments
Milestone

Comments

@rsc
Copy link
Contributor

rsc commented Nov 7, 2014

The really tiny GCs (of less than 1 MB) are very sensitive to constant overheads in the
GC.
The usual 2x policy doesn't work great if the program has a consistent live data set of
100 kB.
There are tons of GCs and the constants dominate.

Should we set a minimum heap size for GC like 1 MB, so that even if the previous GC
ended with 100 kB of live data, we still wait until 1 MB (not 200 kB) before the next
one?
@RLH
Copy link
Contributor

RLH commented Nov 7, 2014

Comment 1:

Perhaps 1Mbyte per P makes more sense since it accounts, at lease
indirectly, for allocation rate. In any case this entire triggering story
is going to change for 1.5 and this can be part of that entire
investigation.

@griesemer
Copy link
Contributor

Comment 2:

Should run http://play.golang.org/p/1DYpDKTclu with -bench flag to confirm effectiveness
of a fix. If the fix is effective, the results for opt = false and opt = true in the
benchmark should become almost identical.

@rsc
Copy link
Contributor Author

rsc commented Nov 12, 2014

Comment 3:

Just to be very clear about what this issue is about.
This is the first two blocks I get from fibo -bench:
wordsize = 64, half = true, opt = false
        n  alloc count  alloc bytes        ns/op        time/op
        1            1            8           47           47ns
       10           10          440         1866        1.866µs
      100          100         4856        19352       19.352µs
     1000         1000        90928       266349      266.349µs
    10000        10000      5009072     13658233    13.658233ms
   100000       100000    464595504    796448601   796.448601ms
  1000000      1000000  46473013296  45115693932  45.115693932s
wordsize = 64, half = true, opt = true
        n  alloc count  alloc bytes        ns/op        time/op
        1            1            8           50           50ns
       10            4          152          879          879ns
      100            4          152         3116        3.116µs
     1000           10          808        48775       48.775µs
    10000           67        32041      2496247     2.496247ms
   100000          653      3020720    189547157   189.547157ms
  1000000         6511    302471600  19298381666  19.298381666s
If I add a single line to the top of the program allocating a 1M-entry int slice:
    var x = make([]int, 1e6)
Then that makes the live data much larger which reduces the frequency of GC, which
amortizes the constant overheads of the GC across more allocations, making them less
dominant. The output changes to:
wordsize = 64, half = true, opt = false
        n  alloc count  alloc bytes        ns/op        time/op
        1            1            8           27           27ns
       10           10          440          852          852ns
      100          100         4856         8876        8.876µs
     1000         1000        90920       110815      110.815µs
    10000        10000      5009065      3566628     3.566628ms
   100000       100000    464595504    284322957   284.322957ms
  1000000      1000000  46473013296  26231074326  26.231074326s
wordsize = 64, half = true, opt = true
        n  alloc count  alloc bytes        ns/op        time/op
        1            1            8           27           27ns
       10            4          152          423          423ns
      100            4          152         2150         2.15µs
     1000           10          808        36378       36.378µs
    10000           67        32040      2081211     2.081211ms
   100000          653      3020715    188221970    188.22197ms
  1000000         6511    302471600  19495001468  19.495001468s
This issue is about making that the output even without the 'var x' line, so that
collecting tiny heaps is not worse than collecting heaps of a few MB.
I am not sure what #2 means by 'almost identical', but this issue is not about bringing
the opt=false and opt=true cases any closer than that.

@dvyukov
Copy link
Member

dvyukov commented Nov 13, 2014

Comment 4:

What has changed since https://golang.org/cl/9837043 ?

@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014
@rsc rsc removed accepted labels Apr 14, 2015
@aclements
Copy link
Member

813e97b introduced a heap minimum of 4MB and later b6e178e updated this so the heap minimum is 4MB * (GOGC/100).

@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants