mirror of
https://github.com/ruby/ruby.git
synced 2026-11-08 01:20:26 +08:00
Recently we added some keys to GC.stat in order to measure the GC performance of Ractor local GC and the associated global GC. This commit refactors some of those terms: "global" was used in two places with different meanings which could get confusing. When it was passed to GC.stat as scope: :global it meant "Give me aggregate stats for all the GCs running in this process". Whereas inside the output of GC.stat, global referred to the number of "global" GCs that are run. That is: stop-the-world GCs that run on every ractor heap in the process. Also the global_gc_count that GC.stat reports for a Ractor ignored global GCs that other Ractors started, even though they swept its heap. In this commit we fix this confusing behaviour, and make the GC.stat output more consistent. We've replaced the scope: parameter to GC.stat with the boolean process: keyword arg. The default is process: false which means GC.stat will return stats for the Ractor that executes the code (the main Ractor if no other Ractors have been created). process: true will return aggregate stats over all the Ractors in the process (including dead ones). Inside GC.stat(process: false), count and global_gc_count now include every global GC that has swept that Ractor's heap. So Ractor local gc count == count - global_gc_count. heap_marked_slots now counts only the marked objects in that Ractor's own heap. Before, the Ractor that started a global GC counted the marked objects of every heap, and the other Ractors reported 0. We also provide a new key global_gc_invocation_count that is the number of global GCs that have been triggered by the Ractor in question. We've also moved some keys related to the global page pool out of the default GC.stat output and into GC.stat(process: true), because they are process-wide and not Ractor specific.
31 lines
884 B
Ruby
31 lines
884 B
Ruby
Warning[:experimental] = false
|
|
GC.measure_total_time = true
|
|
|
|
workers = 4.times.map do |worker_id|
|
|
Ractor.new(worker_id) do |id|
|
|
Ractor.receive # Wait until all workers have been created.
|
|
20.times do |batch|
|
|
Array.new(10_000) { |i| "#{id}:#{batch}:#{i}".reverse }.sort!
|
|
end
|
|
GC.start(full_mark: false)
|
|
{
|
|
ractor: "worker-#{id}",
|
|
marking_time_ms: GC.stat(:marking_time),
|
|
sweeping_time_ms: GC.stat(:sweeping_time)
|
|
}
|
|
end
|
|
end
|
|
|
|
workers.each { |worker| worker.send(:start) }
|
|
workers.each { |worker| p worker.value }
|
|
p({
|
|
ractor: "main",
|
|
marking_time_ms: GC.stat(:marking_time),
|
|
sweeping_time_ms: GC.stat(:sweeping_time)
|
|
})
|
|
|
|
puts "process-wide GC statistics:"
|
|
p GC.stat(process: true)
|
|
puts "process marking time (ms): #{GC.stat(:marking_time, process: true)}"
|
|
puts "process sweeping time (ms): #{GC.stat(:sweeping_time, process: true)}"
|