123456789_123456789_123456789_123456789_123456789_

Module: GC

Relationships & Source Files
Defined in: gc.rb,
gc.c

Overview

The GC module provides an interface to Ruby’s mark-and-sweep garbage collection mechanism.

Some of the underlying methods are also available via the ::ObjectSpace module.

You may obtain information about the operation of the GC through Profiler.

Class Attribute Summary

Class Method Summary

Instance Method Summary

Class Attribute Details

.measure_total_timeBoolean (rw)

Returns the setting for GC total time measurement; the initial setting is true. See .total_time.

[ GitHub ]

  
# File 'gc.rb', line 554

def self.measure_total_time
  Primitive.cexpr! %{
    RBOOL(rb_gc_impl_get_measure_total_time(rb_gc_get_objspace()))
  }
end

.measure_total_time=(setting) ⇒ setting (rw)

Enables or disables GC total time measurement; returns setting. See .total_time.

When argument object is nil or false, disables total time measurement; .measure_total_time then returns false:

GC.measure_total_time = nil   # => nil
GC.measure_total_time         # => false
GC.measure_total_time = false # => false
GC.measure_total_time         # => false

Otherwise, enables total time measurement; .measure_total_time then returns true:

GC.measure_total_time = true # => true
GC.measure_total_time        # => true
GC.measure_total_time = :foo # => :foo
GC.measure_total_time        # => true

Note that when enabled, total time measurement affects performance.

[ GitHub ]

  
# File 'gc.rb', line 541

def self.measure_total_time=(flag)
  Primitive.cstmt! %{
    rb_gc_impl_set_measure_total_time(rb_gc_get_objspace(), flag);
    return flag;
  }
end

.stresssetting (rw)

Returns the current GC stress-mode setting, which initially is false.

The stress mode may be set by method .stress=.

[ GitHub ]

  
# File 'gc.rb', line 87

def self.stress
  Primitive.gc_stress_get
end

.stress=(value) ⇒ value (rw)

Enables or disables stress mode; enabling stress mode will degrade performance; it is only for debugging.

Sets the current GC stress mode to the given value:

  • If the value is nil or false, disables stress mode.

  • If the value is an integer, enables stress mode with certain flags; see below.

  • Otherwise, enables stress mode; GC is invoked at every GC opportunity: all memory and object allocations.

The flags are bits in the given integer:

  • 0x01: No major GC.

  • 0x02: No immediate sweep.

  • 0x04: Full mark after malloc/calloc/realloc.

[ GitHub ]

  
# File 'gc.rb', line 111

def self.stress=(flag)
  Primitive.gc_stress_set_m flag
end

Class Method Details

.configHash .config(hash_to_merge) ⇒ Hash

This method is implementation-specific to CRuby.

Sets or gets information about the current GC configuration.

Configuration parameters are GC implementation-specific and may change without notice.

With no argument given, returns a hash containing the configuration:

GC.config
# => {rgengc_allow_full_mark: true, implementation: "default"}

With argument hash_to_merge given, merges that hash into the stored configuration hash; ignores unknown hash keys; returns the configuration hash:

GC.config(rgengc_allow_full_mark: false)
# => {rgengc_allow_full_mark: false, implementation: "default"}
GC.config(foo: 'bar')
# => {rgengc_allow_full_mark: false, implementation: "default"}

All-Implementations Configuration

The single read-only entry for all implementations is:

  • :implementation: the string name of the implementation; for the Ruby default implementation, 'default'.

Implementation-Specific Configuration

A GC implementation maintains its own implementation-specific configuration.

For Ruby’s default implementation the single entry is:

  • :rgengc_allow_full_mark: Controls whether the GC is allowed to run a full mark (young & old objects):

    • true (default): GC interleaves major and minor collections. A flag is set to notify GC that a full mark has been requested. This flag is accessible via GC.latest_gc_info(:need_major_by).

    • false: GC does not initiate a full marking cycle unless explicitly directed by user code; see GC.start. Setting this parameter to false disables young-to-old promotion. For performance reasons, we recommended warming up the application using Process.warmup before setting this parameter to false.

[ GitHub ]

  
# File 'gc.rb', line 449

def self.config hash = nil
  if Primitive.cexpr!("RBOOL(RB_TYPE_P(hash, T_HASH))")
    if hash.include?(:implementation)
      raise ArgumentError, 'Attempting to set read-only key "Implementation"'
    end

    Primitive.gc_config_set hash
  elsif hash != nil
    raise ArgumentError
  end

  Primitive.gc_config_get
end

.countInteger

Returns the total number of times garbage collection has occurred:

GC.count # => 385
GC.start
GC.count # => 386
[ GitHub ]

  
# File 'gc.rb', line 124

def self.count
  Primitive.gc_count
end

.disableBoolean

Disables garbage collection (but .start remains potent): returns whether garbage collection was already disabled.

GC.enable
GC.disable # => false
GC.disable # => true
[ GitHub ]

  
# File 'gc.rb', line 76

def self.disable
  Primitive.gc_disable
end

.enableBoolean

Enables garbage collection; returns whether garbage collection was disabled:

GC.disable
GC.enable # => true
GC.enable # => false
[ GitHub ]

  
# File 'gc.rb', line 62

def self.enable
  Primitive.gc_enable
end

.latest_gc_infoHash .latest_gc_info(key) ⇒ value .latest_gc_info(hash) ⇒ Hash

With no argument given, returns information about the most recent garbage collection:

GC.latest_gc_info
# =>
{major_by: :force,
 need_major_by: nil,
 gc_by: :method,
 have_finalizer: false,
 immediate_sweep: true,
 state: :none,
 weak_references_count: 0,
 retained_weak_references_count: 0}

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

GC.latest_gc_info(:gc_by) # => :newobj

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

h = {foo: 0, bar: 1}
GC.latest_gc_info(h)
# =>
{foo: 0,
 bar: 1,
 major_by: nil,
 need_major_by: nil,
 gc_by: :newobj,
 have_finalizer: false,
 immediate_sweep: false,
 state: :sweeping,
 weak_references_count: 0,
 retained_weak_references_count: 0}
[ GitHub ]

  
# File 'gc.rb', line 505

def self.latest_gc_info hash_or_key = nil
  if hash_or_key == nil
    hash_or_key = {}
  elsif Primitive.cexpr!("RBOOL(!SYMBOL_P(hash_or_key) && !RB_TYPE_P(hash_or_key, T_HASH))")
    raise TypeError, "non-hash or symbol given"
  end

  Primitive.cstmt! %{
    return rb_gc_latest_gc_info(hash_or_key);
  }
end

.start(full_mark: true, immediate_mark: true, immediate_sweep: true)

Initiates garbage collection, even if explicitly disabled by .disable.

Keyword arguments:

  • full_mark: its boolean value determines whether to perform a major garbage collection cycle:

    • true: initiates a major garbage collection cycle, meaning all objects (old and new) are marked.

    • false: initiates a minor garbage collection cycle, meaning only young objects are marked.

  • immediate_mark: its boolean value determines whether to perform incremental marking:

    • true: marking is completed before the method returns.

    • false: marking is performed by parts, interleaved with program execution both before the method returns and afterward; therefore marking may not be completed before the return. Note that if full_mark is false, marking will always be immediate, regardless of the value of immediate_mark.

  • immediate_sweep: its boolean value determines whether to defer sweeping (using lazy sweep):

    • true: sweeping is completed before the method returns.

    • false: sweeping is performed by parts, interleaved with program execution both before the method returns and afterward; therefore sweeping may not be completed before the return.

Note that these keword arguments are implementation- and version-dependent, are not guaranteed to be future-compatible, and may be ignored in some implementations.

[ GitHub ]

  
# File 'gc.rb', line 43

def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
  Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end

.statHash .stat(key) ⇒ value .stat(hash) ⇒ 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 no argument given, returns information about the most recent garbage collection:

GC.stat
# =>
{count: 28,
 time: 1,
 marking_time: 1,
 sweeping_time: 0,
 heap_allocated_pages: 521,
 heap_empty_pages: 0,
 heap_allocatable_slots: 0,
 heap_available_slots: 539590,
 heap_live_slots: 422243,
 heap_free_slots: 117347,
 heap_final_slots: 0,
 heap_marked_slots: 264877,
 heap_eden_pages: 521,
 total_allocated_pages: 521,
 total_freed_pages: 0,
 total_allocated_objects: 2246376,
 total_freed_objects: 1824133,
 malloc_increase_bytes: 50982,
 malloc_increase_bytes_limit: 18535172,
 minor_gc_count: 18,
 major_gc_count: 10,
 compact_count: 0,
 read_barrier_faults: 0,
 total_moved_objects: 0,
 remembered_wb_unprotected_objects: 0,
 remembered_wb_unprotected_objects_limit: 2162,
 old_objects: 216365,
 old_objects_limit: 432540,
 oldmalloc_increase_bytes: 1654232,
 oldmalloc_increase_bytes_limit: 16846103}

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

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:

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 (count includes both minor and major garbage collections).

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

  • :heap_allocated_pages: The total number of :heap_eden_pages + :heap_tomb_pages.

  • :heap_sorted_length: The number of pages that can fit into the buffer that holds references to all pages.

  • :heap_allocatable_pages: The total number of pages the application could allocate without additional GC.

  • :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.

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

  • :heap_tomb_pages: The total number of pages which do not contain any live slots.

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

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

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

  • :total_freed_objects: The cumulative number of objects 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.

  • :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.

[ GitHub ]

  
# File 'gc.rb', line 250

def self.stat hash_or_key = nil
  Primitive.gc_stat hash_or_key
end

.stat_heapHash .stat_heap(heap_id) ⇒ Hash .stat_heap(heap_id, key) ⇒ value .stat_heap(nil, hash) ⇒ Hash .stat_heap(heap_id, hash) ⇒ Hash

This method is implementation-specific to CRuby.

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

With no argument given, returns statistics for all heaps:

GC.stat_heap
# =>
{0 =>
  {slot_size: 40,
   heap_eden_pages: 246,
   heap_eden_slots: 402802,
   total_allocated_pages: 246,
   force_major_gc_count: 2,
   force_incremental_marking_finish_count: 1,
   total_allocated_objects: 33867152,
   total_freed_objects: 33520523},
 1 =>
  {slot_size: 80,
   heap_eden_pages: 84,
   heap_eden_slots: 68746,
   total_allocated_pages: 84,
   force_major_gc_count: 1,
   force_incremental_marking_finish_count: 4,
   total_allocated_objects: 147491,
   total_freed_objects: 90699},
 2 =>
  {slot_size: 160,
   heap_eden_pages: 157,
   heap_eden_slots: 64182,
   total_allocated_pages: 157,
   force_major_gc_count: 0,
   force_incremental_marking_finish_count: 0,
   total_allocated_objects: 211460,
   total_freed_objects: 190075},
 3 =>
  {slot_size: 320,
   heap_eden_pages: 8,
   heap_eden_slots: 1631,
   total_allocated_pages: 8,
   force_major_gc_count: 0,
   force_incremental_marking_finish_count: 0,
   total_allocated_objects: 1422,
   total_freed_objects: 700},
 4 =>
  {slot_size: 640,
   heap_eden_pages: 16,
   heap_eden_slots: 1628,
   total_allocated_pages: 16,
   force_major_gc_count: 0,
   force_incremental_marking_finish_count: 0,
   total_allocated_objects: 1230,
   total_freed_objects: 309}}

In the example above, the keys in the outer hash are the heap identifiers:

GC.stat_heap.keys # => [0, 1, 2, 3, 4]

On CRuby, each heap identifier is an integer; on other implementations, a heap identifier may be a string.

With only argument heap_id given, returns statistics for the given heap identifier:

GC.stat_heap(2)
# =>
{slot_size: 160,
 heap_eden_pages: 157,
 heap_eden_slots: 64182,
 total_allocated_pages: 157,
 force_major_gc_count: 0,
 force_incremental_marking_finish_count: 0,
 total_allocated_objects: 225018,
 total_freed_objects: 206647}

With arguments heap_id and key given, returns the value for the given key in the given heap:

GC.stat_heap(2, :slot_size) # => 160

With arguments nil and hash given, merges the statistics for all heaps into the given hash:

h = {foo: 0, bar: 1}
GC.stat_heap(nil, h).keys # => [:foo, :bar, 0, 1, 2, 3, 4]

With arguments heap_id and hash given, merges the statistics for the given heap into the given hash:

h = {foo: 0, bar: 1}
GC.stat_heap(2, h).keys
# =>
[:foo,
 :bar,
 :slot_size,
 :heap_eden_pages,
 :heap_eden_slots,
 :total_allocated_pages,
 :force_major_gc_count,
 :force_incremental_marking_finish_count,
 :total_allocated_objects,
 :total_freed_objects]

The statistics for a heap may include:

  • :slot_size: The slot size of the heap in bytes.

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

  • :heap_eden_pages: The number of pages in the eden heap.

  • :heap_eden_slots: The total number of slots in all of the pages in the eden heap.

  • :heap_tomb_pages: The number of pages in the tomb heap. The tomb heap only contains pages that do not have any live objects.

  • :heap_tomb_slots: The total number of slots in all of the pages in the tomb heap.

  • :total_allocated_pages: The total number of pages that have been allocated in the heap.

  • :total_freed_pages: The total number of pages that have been freed and released back to the system in the heap.

  • :force_major_gc_count: The number of times this heap has forced major garbage collection cycles to start due to running out of free slots.

  • :force_incremental_marking_finish_count: The number of times this heap has forced incremental marking to complete due to running out of pooled slots.

[ GitHub ]

  
# File 'gc.rb', line 394

def self.stat_heap heap_name = nil, hash_or_key = nil
  Primitive.gc_stat_heap heap_name, hash_or_key
end

.total_timeInteger

Returns the GC total time in nanoseconds:

GC.total_time # => 156250

Note that total time accumulates only when total time measurement is enabled (that is, when .measure_total_time is true):

GC.measure_total_time # => true
GC.total_time # => 625000
GC.start
GC.total_time # => 937500
GC.start
GC.total_time # => 1093750

GC.measure_total_time = false
GC.total_time # => 1250000
GC.start
GC.total_time # => 1250000
GC.start
GC.total_time # => 1250000

GC.measure_total_time = true
GC.total_time # => 1250000
GC.start
GC.total_time # => 1406250
[ GitHub ]

  
# File 'gc.rb', line 590

def self.total_time
  Primitive.cexpr! %{
    ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace()))
  }
end

Instance Method Details

#garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true)

Alias of .start

[ GitHub ]

  
# File 'gc.rb', line 48

def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
  Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end