Skip to content

Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →

class method

GC.stat

(?::Hash[::Symbol, untyped]? hash) -> ::Hash[::Symbol, untyped]
(::Symbol key) -> ::Integer
GC.stat(scope: :ractor) → new_hash
GC.stat(key, scope: :ractor) → value
GC.stat(hash, scope: :ractor) → hash

This method is implementation-specific to CRuby.

Returns GC statistics. The particular statistics are implementation-specific and may change in the future without notice.

With scope: :ractor (the default) or scope: :local, returns statistics for the current Ractor’s object space. With scope: :global, returns cumulative collection counts and measured GC time across all Ractors.

With no positional argument or nil given, returns a hash containing the GC statistics:

Example
GC.stat
# =>
{count: 1,
 time: 0,
 marking_time: 0,
 sweeping_time: 0,
 total_malloc_bytes: 10432791,
 total_free_bytes: 6989873,
 heap_allocated_pages: 41,
 heap_empty_pages: 0,
 heap_allocatable_bytes: 228656,
 heap_eden_pages: 41,
 total_allocated_pages: 41,
 total_freed_pages: 0,
 malloc_increase_bytes: 0,
 malloc_increase_bytes_limit: 16777216,
 minor_gc_count: 0,
 major_gc_count: 1,
 global_gc_count: 0,
 compact_count: 0,
 read_barrier_faults: 0,
 total_moved_objects: 0,
 remembered_wb_unprotected_objects: 0,
 remembered_wb_unprotected_objects_limit: 7,
 old_objects: 721,
 old_objects_limit: 1442,
 oldmalloc_increase_bytes: 0,
 oldmalloc_increase_bytes_limit: 16777216,
 total_allocated_objects: 36735,
 total_freed_objects: 19527,
 heap_available_slots: 40591,
 heap_live_slots: 17208,
 heap_free_slots: 23383,
 heap_final_slots: 0,
 heap_marked_slots: 17175}

With symbol argument key given, returns the value for that key:

Example
GC.stat(:count) # => 30

With hash argument hash given, returns that hash with GC statistics merged into its content; this form may be useful in minimizing probe effects:

Example
h = {foo: 0, bar: 1}
GC.stat(h)
h.keys.take(5) # => [:foo, :bar, :count, :time, :marking_time]

The hash includes entries such as:

  • :count: The total number of garbage collections run since application start (the count includes minor, major, and global garbage collections).

  • :time: The total time spent in garbage collections (in milliseconds).

  • :marking_time: The total time spent marking objects (in milliseconds).

  • :sweeping_time: The total time spent sweeping objects (in milliseconds).

  • :total_malloc_bytes: The total number of bytes allocated by malloc since application start.

  • :total_free_bytes: The total number of bytes freed since application start.

  • :heap_allocated_pages: The total number of allocated pages.

  • :heap_empty_pages: The number of pages with no live objects, and that could be released to the system.

  • :heap_allocatable_bytes: The number of bytes that can be allocated without triggering a new garbage collection cycle.

  • :heap_eden_pages: The total number of pages which contain at least one live slot.

  • :total_allocated_pages: The cumulative number of pages allocated since application start.

  • :total_freed_pages: The cumulative number of pages freed since application start.

  • :malloc_increase_bytes: Amount of memory allocated on the heap for objects. Decreased by any GC.

  • :malloc_increase_bytes_limit: When :malloc_increase_bytes crosses this limit, GC is triggered.

  • :minor_gc_count: The total number of minor garbage collections run since process start.

  • :major_gc_count: The total number of major garbage collections run since process start. Global garbage collections are counted separately.

  • :global_gc_count: The number of global (stop-the-world) garbage collections this Ractor initiated. Each global garbage collection is attributed to the Ractor that initiated it, so the values sum across Ractors. With scope: :global, the process total, including terminated Ractors.

  • :compact_count: The total number of compactions run since process start.

  • :read_barrier_faults: The total number of times the read barrier was triggered during compaction.

  • :total_moved_objects: The total number of objects compaction has moved.

  • :remembered_wb_unprotected_objects: The total number of objects without write barriers.

  • :remembered_wb_unprotected_objects_limit: When :remembered_wb_unprotected_objects crosses this limit, major GC is triggered.

  • :old_objects: Number of live, old objects which have survived at least 3 garbage collections.

  • :old_objects_limit: When :old_objects crosses this limit, major GC is triggered.

  • :oldmalloc_increase_bytes: Amount of memory allocated on the heap for objects. Decreased by major GC.

  • :oldmalloc_increase_bytes_limit: When :oldmalloc_increase_bytes crosses this limit, major GC is triggered.

  • :total_allocated_objects: The cumulative number of objects allocated since application start.

  • :total_freed_objects: The cumulative number of objects freed since application start.

  • :heap_available_slots: The total number of slots in all :heap_allocated_pages.

  • :heap_live_slots: The total number of slots which contain live objects.

  • :heap_free_slots: The total number of slots which do not contain live objects.

  • :heap_final_slots: The total number of slots with pending finalizers to be run.

  • :heap_marked_slots: The total number of objects marked in the last GC.

Global scope

With scope: :global, the default collector reports cumulative collection counts and measured CPU time across all Ractors, retaining history from destroyed object spaces:

Example
GC.stat(scope: :global)
# => {count: 42, minor_gc_count: 32, major_gc_count: 8,
#     global_gc_count: 2,
#     time: 3, marking_time: 2, sweeping_time: 1}

These totals include both local and global collections, and :count equals :minor_gc_count plus :major_gc_count plus :global_gc_count in both scopes.

:global_gc_count attributes each global collection to the Ractor that initiated it, and the total retains the counts of terminated Ractors.

:time may exceed :marking_time plus :sweeping_time by one millisecond because raw nanoseconds are summed before conversion. Times measure collector CPU work, not wall-clock pauses.

Reads combine object-space publications without requesting a stop-the-world barrier. GC.measure_total_time controls future timing accumulation. Profiler controls do not affect these totals. A forked child inherits its parent’s totals. MMTk and wbcheck raise NotImplementedError for this scope.

Unknown scopes and unavailable keys raise ArgumentError.

Ruby version changes

  1. 4.1
    • GC.stat accepts scope: :ractor (the default), scope: :local (a synonym for :ractor), and scope: :global. With the default collector, the global scope reports cumulative collection counts and measured marking/sweeping CPU time across Ractors, including history from destroyed object spaces, without requesting a stop-the-world snapshot. Unscoped GC.stat, GC.count, and GC.total_time retain their current-Ractor behavior.

    • GC.stat reports a new key, :global_gc_count: the number of stop-the-world global garbage collection cycles the current Ractor initiated. Each global collection is attributed to exactly one Ractor, so the values sum across Ractors. GC.stat(:global_gc_count, scope: :global) reports the process total, including the counts of terminated Ractors.

  2. 3.1
    • “GC.measure_total_time = true” enables the measurement of GC. Measurement can introduce overhead. It is enabled by default. GC.measure_total_time returns the current setting. GC.stat[:time] or GC.stat(:time) returns measured time in milli-seconds. [[Feature #10917]]

See also .start .stat_heap .remove_stress_to_class .stress also in 4.0 · 3.4 · 3.3 · 3.2 · 3.1 · 3.0