Skip to content

Commit

Permalink
Force double GC
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexJF committed Dec 20, 2023
1 parent a598746 commit 47dd4f4
Showing 1 changed file with 12 additions and 15 deletions.
27 changes: 12 additions & 15 deletions spec/datadog/profiling/stack_recorder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def sample_allocation(obj)
._native_sample(Thread.current, stack_recorder, metric_values, labels, numeric_labels, 400, false)
end

def do_starting_allocations
before do
allocations = [a_string, an_array, "a fearsome interpolated string: #{sample_rate}", (-10..-1).to_a, a_hash,
{ 'z' => -1, 'y' => '-2', 'x' => false }, Object.new]
@num_allocations = 0
Expand All @@ -377,22 +377,18 @@ def do_starting_allocations
# Do a thorough cleanup of the allocations array. We witnessed some flakiness
# with just a simple clear call which is why we added the map and put this all
# in the same function.
allocations.map! { nil }
allocations.clear

# At this point plus the return from this call, there should be no way for any
# object to still be considered alive in any way (for example, in some CPU register)
nil
end

before do
# Do a bunch of allocations, cleaning up references to all, except the objects kept
# alive by the lets. We could inline this but the extra call should hopefully help
# clear any unintentional references or remains in CPU registers and such.
do_starting_allocations
# This GC should collect those sampled allocations that are not being kept alive by
# the lets.
GC.start
# NOTE: We've witnessed CI flakiness where the last entry of allocations may still be alive
# after the previous GC. We've experimentally noticed this is no longer the case if
# we do a second GC.
# This might be an instance of the issues described in https://bugs.ruby-lang.org/issues/19460
# and https://bugs.ruby-lang.org/issues/19041. We didn't get to the bottom of the
# reason but it might be that some machine context/register ends up still pointing to
# that last entry and thus manages to get it marked in the first GC.
GC.start
end

Expand Down Expand Up @@ -421,11 +417,12 @@ def do_starting_allocations
# We sample from 2 distinct locations
expect(heap_samples.size).to eq(2)

# FIXME: Remove, this is just for debugging purposes
described_class::Testing._native_debug_heap_recorder(stack_recorder)

sum_heap_samples = 0
heap_samples.each { |s| sum_heap_samples += s.values[:'heap-live-samples'] }

# FIXME: Remove, this is just for debugging purposes
described_class::Testing._native_debug_heap_recorder(stack_recorder) if sum_heap_samples != 150

expect(sum_heap_samples).to eq([a_string, an_array, a_hash].size * sample_rate)
end

Expand Down

0 comments on commit 47dd4f4

Please sign in to comment.