Class: Autotuner::Heuristic::RememberedWBUnprotectedObjects

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

Constant Summary collapse

WB_UNPROTECTED_GC_RATIO_THRESHOLD =
0.1
MIN_WB_UNPROTECTED_GC =
10
DEFAULT_LIMIT_RATIO =

From the GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO macro github.com/ruby/ruby/blob/df4c77608e76068deed58b2781674b0eb247c325/gc.c#L295

0.01
LIMIT_RATIO_ENV =
"RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

disable!, enabled?

Constructor Details

#initialize(_system_context) ⇒ RememberedWBUnprotectedObjects

Returns a new instance of RememberedWBUnprotectedObjects.



25
26
27
28
29
30
31
32
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 25

def initialize(_system_context)
  super

  @major_gc_count = 0
  @remembered_wb_unprotected_gc_count = 0

  @given_suggestion = false
end

Instance Attribute Details

#major_gc_countObject (readonly)

Returns the value of attribute major_gc_count.



22
23
24
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 22

def major_gc_count
  @major_gc_count
end

#remembered_wb_unprotected_gc_countObject (readonly)

Returns the value of attribute remembered_wb_unprotected_gc_count.



23
24
25
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 23

def remembered_wb_unprotected_gc_count
  @remembered_wb_unprotected_gc_count
end

Class Method Details

.supported?Boolean

Returns:

  • (Boolean)


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

def supported?
  # Ruby 3.3.0 and later have support RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO
  RUBY_VERSION >= "3.3.0"
end

Instance Method Details

#call(request_context) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 38

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
  @remembered_wb_unprotected_gc_count += 1 if request_context.after_gc_context.latest_gc_info[:major_by] == :shady
end

#debug_stateObject



76
77
78
79
80
81
82
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 76

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

#nameObject



34
35
36
# File 'lib/autotuner/heuristic/remembered_wb_unprotected_objects.rb', line 34

def name
  "WBUnprotectedObjects"
end

#tuning_reportObject



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

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

  wb_unprotected_gc_ratio = @remembered_wb_unprotected_gc_count.to_f / @major_gc_count
  # Don't report if there's very few WB unprotected GC
  return if wb_unprotected_gc_ratio <= WB_UNPROTECTED_GC_RATIO_THRESHOLD

  @given_suggestion = true

  Report::SingleEnvironmentVariable.new(
    <<~MSG,
      The following suggestions reduce the number of major garbage collection cycles, specifically a cycle called "remembered write barrier unprotected" (also know as "shady" due to historical reasons). Your app runs remembered write barrier unprotected cycles in approximately #{format("%.2f", wb_unprotected_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_RATIO_ENV,
    suggested_limit_ratio,
    configured_limit_ratio,
  )
end