github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/util/gctuner/README.md (about)

     1  # gctuner
     2  
     3  ## Introduction
     4  
     5  Inspired
     6  by [How We Saved 70K Cores Across 30 Mission-Critical Services (Large-Scale, Semi-Automated Go GC Tuning @Uber)](https://eng.uber.com/how-we-saved-70k-cores-across-30-mission-critical-services/)
     7  .
     8  
     9  ```text
    10   _______________  => limit: host/cgroup memory hard limit
    11  |               |
    12  |---------------| => gc_trigger: heap_live + heap_live * GCPercent / 100
    13  |               |
    14  |---------------|
    15  |   heap_live   |
    16  |_______________|
    17  ```
    18  
    19  Go runtime trigger GC when hit `gc_trigger` which affected by `GCPercent` and `heap_live`.
    20  
    21  Assuming that we have stable traffic, our application will always have 100 MB live heap, so the runtime will trigger GC
    22  once heap hits 200 MB(by default GOGC=100). The heap size will be changed like: `100MB => 200MB => 100MB => 200MB => ...`.
    23  
    24  But in real production, our application may have 4 GB memory resources, so no need to GC so frequently.
    25  
    26  The gctuner helps to change the GOGC(GCPercent) dynamically at runtime, set the appropriate GCPercent according to current
    27  memory usage.
    28  
    29  ### How it works
    30  
    31  ```text
    32   _______________  => limit: host/cgroup memory hard limit
    33  |               |
    34  |---------------| => threshold: increase GCPercent when gc_trigger < threshold
    35  |               |
    36  |---------------| => gc_trigger: heap_live + heap_live * GCPercent / 100
    37  |               |
    38  |---------------|
    39  |   heap_live   |
    40  |_______________|
    41  
    42  threshold = inuse + inuse * (gcPercent / 100)
    43  => gcPercent = (threshold - inuse) / inuse * 100
    44  
    45  if threshold < 2*inuse, so gcPercent < 100, and GC positively to avoid OOM
    46  if threshold > 2*inuse, so gcPercent > 100, and GC negatively to reduce GC times
    47  ```
    48  
    49  ## Usage
    50  
    51  The recommended threshold is 70% of the memory limit.
    52  
    53  ```go
    54  
    55  // Get mem limit from the host machine or cgroup file.
    56  limit := 4 * 1024 * 1024 * 1024
    57  threshold := limit * 0.7
    58  
    59  gctuner.Tuning(threshold)
    60  ```