# <!-- rdoc-file=gc.rb -->
# 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 GC::Profiler.
#
module GC
  # <!-- rdoc-file=gc.c -->
  # The GC profiler provides access to information on GC runs including time,
  # length and object space size.
  #
  # Example:
  #
  #     GC::Profiler.enable
  #
  #     require 'rdoc/rdoc'
  #
  #     GC::Profiler.report
  #
  #     GC::Profiler.disable
  #
  # See also GC.count, GC.malloc_allocated_size and GC.malloc_allocations
  #
  module Profiler
    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.clear          -> nil
    # -->
    # Clears the GC profiler data.
    #
    def self.clear: () -> nil

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.disable      -> nil
    # -->
    # Stops the GC profiler.
    #
    def self.disable: () -> nil

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.enable       -> nil
    # -->
    # Starts the GC profiler.
    #
    def self.enable: () -> nil

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.enabled?     -> true or false
    # -->
    # The current status of GC profile mode.
    #
    def self.enabled?: () -> bool

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.raw_data    -> [Hash, ...]
    # -->
    # Returns an Array of individual raw profile data Hashes ordered from earliest
    # to latest by `:GC_INVOKE_TIME`.
    #
    # For example:
    #
    #     [
    #       {
    #          :GC_TIME=>1.3000000000000858e-05,
    #          :GC_INVOKE_TIME=>0.010634999999999999,
    #          :HEAP_USE_SIZE=>289640,
    #          :HEAP_TOTAL_SIZE=>588960,
    #          :HEAP_TOTAL_OBJECTS=>14724,
    #          :GC_IS_MARKED=>false
    #       },
    #       # ...
    #     ]
    #
    # The keys mean:
    #
    # `:GC_TIME`
    # :   Time elapsed in seconds for this GC run
    #
    # `:GC_INVOKE_TIME`
    # :   Time elapsed in seconds from startup to when the GC was invoked
    #
    # `:HEAP_USE_SIZE`
    # :   Total bytes of heap used
    #
    # `:HEAP_TOTAL_SIZE`
    # :   Total size of heap in bytes
    #
    # `:HEAP_TOTAL_OBJECTS`
    # :   Total number of objects
    #
    # `:GC_IS_MARKED`
    # :   Returns `true` if the GC is in mark phase
    #
    #
    # If ruby was built with `GC_PROFILE_MORE_DETAIL`, you will also have access to
    # the following hash keys:
    #
    # `:GC_MARK_TIME`
    # `:GC_SWEEP_TIME`
    # `:ALLOCATE_INCREASE`
    # `:ALLOCATE_LIMIT`
    # `:HEAP_USE_PAGES`
    # `:HEAP_LIVE_OBJECTS`
    # `:HEAP_FREE_OBJECTS`
    # `:HAVE_FINALIZE`
    # :
    #
    def self.raw_data: () -> Array[Hash[Symbol, untyped]]?

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.report
    #   - GC::Profiler.report(io)
    # -->
    # Writes the GC::Profiler.result to `$stdout` or the given IO object.
    #
    def self.report: (?_Reporter io) -> nil

    interface _Reporter
      def write: (String msg) -> void
    end

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.result  -> String
    # -->
    # Returns a profile data report such as:
    #
    #     GC 1 invokes.
    #     Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
    #         1               0.012               159240               212940                10647         0.00000000000001530000
    #
    def self.result: () -> String

    # <!--
    #   rdoc-file=gc.c
    #   - GC::Profiler.total_time  -> float
    # -->
    # The total time used for garbage collection in seconds
    #
    def self.total_time: () -> Float
  end

  # <!-- rdoc-file=gc.c -->
  # Internal constants in the garbage collector.
  #
  INTERNAL_CONSTANTS: Hash[Symbol, untyped]

  # <!-- rdoc-file=gc.c -->
  # GC build options
  #
  OPTS: Array[String]

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.config -> hash
  #   - GC.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`.
  #
  def self.config: () -> Hash[Symbol, untyped]
                 | (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]

  # <!--
  #   rdoc-file=gc.rb
  #   - self.count -> integer
  # -->
  # Returns the total number of times garbage collection has occurred:
  #
  #     GC.count # => 385
  #     GC.start
  #     GC.count # => 386
  #
  def self.count: () -> Integer

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.disable -> true or false
  # -->
  # Disables garbage collection (but GC.start remains potent): returns whether
  # garbage collection was already disabled.
  #
  #     GC.enable
  #     GC.disable # => false
  #     GC.disable # => true
  #
  def self.disable: () -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.enable -> true or false
  # -->
  # Enables garbage collection; returns whether garbage collection was disabled:
  #
  #     GC.disable
  #     GC.enable # => true
  #     GC.enable # => false
  #
  def self.enable: () -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - start(full_mark: true, immediate_mark: true, immediate_sweep: true)
  # -->
  # Initiates garbage collection, even if explicitly disabled by GC.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 keyword arguments are implementation- and version-dependent,
  # are not guaranteed to be future-compatible, and may be ignored in some
  # implementations.
  #
  def self.start: (?immediate_sweep: boolish, ?immediate_mark: boolish, ?full_mark: boolish) -> nil

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stat -> new_hash
  #   - GC.stat(key) -> value
  #   - GC.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](https://en.wikipedia.org/wiki/Probe_effect):
  #
  #     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 allocated pages.
  # *   `:heap_empty_pages`: The number of pages with no live objects, and that
  #     could be released to the system.
  # *   `: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.
  # *   `: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.
  #
  def self.stat: (?Hash[Symbol, untyped]? hash) -> Hash[Symbol, untyped]
               | (Symbol key) -> Integer

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.measure_total_time = setting -> setting
  # -->
  # Enables or disables GC total time measurement; returns `setting`. See
  # GC.total_time.
  #
  # When argument `object` is `nil` or `false`, disables total time measurement;
  # GC.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; GC.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.
  #
  def self.measure_total_time=: [T] (T enable) -> T

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.measure_total_time -> true or false
  # -->
  # Returns the setting for GC total time measurement; the initial setting is
  # `true`. See GC.total_time.
  #
  def self.measure_total_time: () -> bool

  # <!--
  #   rdoc-file=gc.c
  #   - GC.auto_compact = flag
  # -->
  # Updates automatic compaction mode.
  #
  # When enabled, the compactor will execute on every major collection.
  #
  # Enabling compaction will degrade performance on major collections.
  #
  def self.auto_compact=: [T] (T enable) -> T

  # <!--
  #   rdoc-file=gc.c
  #   - GC.auto_compact    -> true or false
  # -->
  # Returns whether or not automatic compaction has been enabled.
  #
  def self.auto_compact: () -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stat_heap -> new_hash
  #   - GC.stat_heap(heap_id) -> new_hash
  #   - GC.stat_heap(heap_id, key) -> value
  #   - GC.stat_heap(nil, hash) -> hash
  #   - GC.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.
  # *   `: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.
  #
  def self.stat_heap: (?Integer? heap_name, ?Hash[Symbol, untyped]? hash) -> Hash[Symbol, untyped]
                    | (Integer heap_name, Symbol key) -> Integer

  # <!--
  #   rdoc-file=gc.c
  #   - GC.latest_compact_info -> hash
  # -->
  # Returns information about object moved in the most recent GC compaction.
  #
  # The returned hash has two keys :considered and :moved.  The hash for
  # :considered lists the number of objects that were considered for movement by
  # the compactor, and the :moved hash lists the number of objects that were
  # actually moved.  Some objects can't be moved (maybe they were pinned) so these
  # numbers can be used to calculate compaction efficiency.
  #
  def self.latest_compact_info: () -> compact_info

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stress -> setting
  # -->
  # Returns the current GC stress-mode setting, which initially is `false`.
  #
  # The stress mode may be set by method GC.stress=.
  #
  def self.stress: () -> (Integer | bool)

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stress = value -> value
  # -->
  # 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.
  #
  def self.stress=: (Integer flag) -> Integer
                  | (bool flag) -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.total_time -> integer
  # -->
  # 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 GC.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
  #
  def self.total_time: () -> Integer

  # <!--
  #   rdoc-file=gc.c
  #   - GC.compact
  # -->
  # This function compacts objects together in Ruby's heap.  It eliminates unused
  # space (or fragmentation) in the heap by moving objects in to that unused
  # space.  This function returns a hash which contains statistics about which
  # objects were moved.  See `GC.latest_gc_info` for details about compaction
  # statistics.
  #
  # This method is implementation specific and not expected to be implemented in
  # any implementation besides MRI.
  #
  # To test whether GC compaction is supported, use the idiom:
  #
  #     GC.respond_to?(:compact)
  #
  def self.compact: () -> compact_info

  # The type that `GC.compact` and related functions can return.
  #
  type compact_info = Hash[:considered | :moved | :moved_up | :moved_down, Hash[Symbol, Integer]]

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
  # -->
  # Verify compaction reference consistency.
  #
  # This method is implementation specific.  During compaction, objects that were
  # moved are replaced with T_MOVED objects.  No object should have a reference to
  # a T_MOVED object after compaction.
  #
  # This function expands the heap to ensure room to move all objects, compacts
  # the heap to make sure everything moves, updates all references, then performs
  # a full GC.  If any object contains a reference to a T_MOVED object, that
  # object should be pushed on the mark stack, and will make a SEGV.
  #
  def self.verify_compaction_references: (?toward: :empty | untyped, ?double_heap: boolish, ?expand_heap: boolish) -> compact_info

  # <!--
  #   rdoc-file=gc.c
  #   - GC.verify_internal_consistency                  -> nil
  # -->
  # Verify internal consistency.
  #
  # This method is implementation specific. Now this method checks generational
  # consistency if RGenGC is supported.
  #
  def self.verify_internal_consistency: () -> nil

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.latest_gc_info -> new_hash
  #   - GC.latest_gc_info(key) -> value
  #   - GC.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](https://en.wikipedia.org/wiki/Probe_effect):
  #
  #     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}
  #
  def self.latest_gc_info: (?Hash[Symbol, untyped]? hash) -> Hash[Symbol, untyped]
                         | (Symbol key) -> untyped

  # <!--
  #   rdoc-file=gc.rb
  #   - garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true)
  # -->
  # Alias of GC.start
  #
  def garbage_collect: (?immediate_sweep: boolish immediate_sweep, ?immediate_mark: boolish immediate_mark, ?full_mark: boolish full_mark) -> nil
end
