Class: Autotuner::Heuristic::Oldmalloc

Inherits:
Base
  • Object
show all
Defined in:
lib/autotuner/heuristic/oldmalloc.rb

Constant Summary collapse

OLDMALLOC_GC_RATIO_THRESHOLD =
0.01
MIN_OLDMALLOC_GC =
10
LIMIT_ENV =
"RUBY_GC_OLDMALLOC_LIMIT"
LIMIT_MAX_ENV =
"RUBY_GC_OLDMALLOC_LIMIT_MAX"
LIMIT_ENV_SUGGESTED_VALUE =

Except for aggressively decreasing memory usage, it doesn’t make sense for Rails apps to run oldmalloc major GC cycles. So we suggest an extremely high value (around 1TB here) to essentially disable it.

1_000_000_000_000
LIMIT_MAX_SUGGESTED_VALUE =
1_000_000_000_000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

disable!, enabled?

Constructor Details

#initialize(_system_context) ⇒ Oldmalloc

Returns a new instance of Oldmalloc.



27
28
29
30
31
32
33
34
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 27

def initialize(_system_context)
  super

  @major_gc_count = 0
  @oldmalloc_gc_count = 0

  @given_suggestion = false
end

Instance Attribute Details

#major_gc_countObject (readonly)

Returns the value of attribute major_gc_count.



24
25
26
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 24

def major_gc_count
  @major_gc_count
end

#oldmalloc_gc_countObject (readonly)

Returns the value of attribute oldmalloc_gc_count.



25
26
27
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 25

def oldmalloc_gc_count
  @oldmalloc_gc_count
end

Class Method Details

.supported?Boolean

Returns:

  • (Boolean)


7
8
9
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 7

def supported?
  true
end

Instance Method Details

#call(request_context) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 40

def call(request_context)
  # major_by is only useful if we ran at least one major GC during the request
  if request_context.after_gc_context.stat[:major_gc_count] ==
      request_context.before_gc_context.stat[:major_gc_count]
    return
  end

  # Technically, we could run more than one major GC in the request, but
  # since we don't have information about the other major GC, we'll treat
  # it as if there was only one major GC.
  @major_gc_count += 1
  @oldmalloc_gc_count += 1 if request_context.after_gc_context.latest_gc_info[:major_by] == :oldmalloc
end

#debug_stateObject



78
79
80
81
82
83
84
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 78

def debug_state
  {
    given_suggestion: @given_suggestion,
    major_gc_count: @major_gc_count,
    oldmalloc_gc_count: @oldmalloc_gc_count,
  }
end

#nameObject



36
37
38
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 36

def name
  "Oldmalloc"
end

#tuning_reportObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/autotuner/heuristic/oldmalloc.rb', line 54

def tuning_report
  # Don't give suggestions twice
  return if @given_suggestion
  # Don't report if there's very few data points
  return if @oldmalloc_gc_count < MIN_OLDMALLOC_GC

  oldmalloc_gc_ratio = @oldmalloc_gc_count.to_f / @major_gc_count
  # Don't report if there's very few oldmalloc GC
  return if oldmalloc_gc_ratio <= OLDMALLOC_GC_RATIO_THRESHOLD

  @given_suggestion = true

  Report::MultipleEnvironmentVariables.new(
    <<~MSG,
      The following suggestions reduce the number of major garbage collection cycles, specifically a cycle called "oldmalloc". Your app runs oldmalloc cycles in approximately #{format("%.2f", oldmalloc_gc_ratio * 100)}% of all major garbage collection cycles.

      Reducing major garbage collection cycles can help reduce response times, especially for the extremes (e.g. p95 or p99 response times). The following tuning values aim to disable oldmalloc garbage collection cycles by setting it to an extremely high value. This may cause a slight increase in memory usage. You should monitor memory usage carefully to ensure your app is not running out of memory.
    MSG
    [LIMIT_ENV, LIMIT_MAX_ENV],
    [LIMIT_ENV_SUGGESTED_VALUE, LIMIT_MAX_SUGGESTED_VALUE],
    [ENV[LIMIT_ENV]&.to_i, ENV[LIMIT_MAX_ENV]&.to_i],
  )
end