summaryrefslogtreecommitdiff
path: root/gc.rb
diff options
context:
space:
mode:
Diffstat (limited to 'gc.rb')
-rw-r--r--gc.rb706
1 files changed, 504 insertions, 202 deletions
diff --git a/gc.rb b/gc.rb
index 9144a96603..48bed27880 100644
--- a/gc.rb
+++ b/gc.rb
@@ -1,303 +1,605 @@
# for gc.c
-# The GC module provides an interface to Ruby's mark and
-# sweep garbage collection mechanism.
+# 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.
+# 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.
+# You may obtain information about the operation of the \GC through GC::Profiler.
module GC
- # call-seq:
- # GC.start -> nil
- # ObjectSpace.garbage_collect -> nil
- # include GC; garbage_collect -> nil
- # GC.start(full_mark: true, immediate_sweep: true) -> nil
- # ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
- # include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
+ # Initiates garbage collection, even if explicitly disabled by GC.disable.
#
- # Initiates garbage collection, even if manually disabled.
+ # Keyword arguments:
#
- # This method is defined with keyword arguments that default to true:
+ # - +full_mark+:
+ # its boolean value determines whether to perform a major garbage collection cycle:
#
- # def GC.start(full_mark: true, immediate_sweep: true); end
+ # - +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.
#
- # Use full_mark: false to perform a minor GC.
- # Use immediate_sweep: false to defer sweeping (use lazy sweep).
+ # - +immediate_mark+:
+ # its boolean value determines whether to perform incremental marking:
#
- # Note: These keyword arguments are implementation and version dependent. They
- # are not guaranteed to be future-compatible, and may be ignored if the
- # underlying implementation does not support them.
+ # - +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 full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end
+ # Alias of GC.start
def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end
- # call-seq:
- # GC.enable -> true or false
+ # call-seq:
+ # GC.enable -> true or false
#
- # Enables garbage collection, returning +true+ if garbage
- # collection was previously disabled.
+ # Enables garbage collection;
+ # returns whether garbage collection was disabled:
#
- # GC.disable #=> false
- # GC.enable #=> true
- # GC.enable #=> false
+ # GC.disable
+ # GC.enable # => true
+ # GC.enable # => false
#
def self.enable
Primitive.gc_enable
end
- # call-seq:
- # GC.disable -> true or false
+ # call-seq:
+ # GC.disable -> true or false
+ #
+ # Disables garbage collection (but GC.start remains potent):
+ # returns whether garbage collection was already disabled.
#
- # Disables garbage collection, returning +true+ if garbage
- # collection was already disabled.
+ # GC.enable
+ # GC.disable # => false
+ # GC.disable # => true
#
- # GC.disable #=> false
- # GC.disable #=> true
def self.disable
Primitive.gc_disable
end
- # call-seq:
- # GC.stress -> integer, true or false
+ # call-seq:
+ # GC.stress -> setting
#
- # Returns current status of GC stress mode.
+ # Returns the current \GC stress-mode setting,
+ # which initially is +false+.
+ #
+ # The stress mode may be set by method GC.stress=.
def self.stress
Primitive.gc_stress_get
end
- # call-seq:
- # GC.stress = flag -> flag
+ # call-seq:
+ # GC.stress = value -> value
+ #
+ # Enables or disables stress mode;
+ # enabling stress mode will degrade performance; it is only for debugging.
#
- # Updates the GC stress mode.
+ # Sets the current \GC stress mode to the given value:
#
- # When stress mode is enabled, the GC is invoked at every GC opportunity:
- # all memory and object allocations.
+ # - 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.
#
- # Enabling stress mode will degrade performance, it is only for debugging.
+ # The flags are bits in the given integer:
+ #
+ # - +0x01+: No major \GC.
+ # - +0x02+: No immediate sweep.
+ # - +0x04+: Full mark after malloc/calloc/realloc.
#
- # flag can be true, false, or an integer bit-ORed following flags.
- # 0x01:: no major GC
- # 0x02:: no immediate sweep
- # 0x04:: full mark after malloc/calloc/realloc
def self.stress=(flag)
Primitive.gc_stress_set_m flag
end
- # call-seq:
- # GC.count -> Integer
+ # call-seq:
+ # self.count -> integer
+ #
+ # Returns the total number of times garbage collection has occurred:
#
- # The number of times GC occurred.
+ # GC.count # => 385
+ # GC.start
+ # GC.count # => 386
#
- # It returns the number of times GC occurred since the process started.
def self.count
Primitive.gc_count
end
- # call-seq:
- # GC.stat -> Hash
- # GC.stat(hash) -> Hash
- # GC.stat(:key) -> Numeric
- #
- # Returns a Hash containing information about the GC.
- #
- # The contents of the hash are implementation specific and may change in
- # the future without notice.
- #
- # The hash includes information about internal statistics about GC such as:
- #
- # [count]
- # The total number of garbage collections ran 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 `:old_malloc_increase_bytes` crosses this limit, major GC is triggered
- #
- # If the optional argument, hash, is given,
- # it is overwritten and returned.
- # This is intended to avoid probe effect.
- #
- # This method is only expected to work on CRuby.
+ # call-seq:
+ # 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_bytes: 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_or_key = nil
Primitive.gc_stat hash_or_key
end
# call-seq:
- # GC.stat_heap -> Hash
- # GC.stat_heap(nil, hash) -> Hash
- # GC.stat_heap(heap_name) -> Hash
- # GC.stat_heap(heap_name, hash) -> Hash
- # GC.stat_heap(heap_name, :key) -> Numeric
+ # 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: 32,
+ # heap_eden_pages: 24,
+ # heap_eden_slots: 12288,
+ # total_allocated_pages: 24,
+ # force_major_gc_count: 0,
+ # force_incremental_marking_finish_count: 0,
+ # total_allocated_objects: 8450,
+ # total_freed_objects: 3120},
+ # 1 =>
+ # {slot_size: 64,
+ # 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},
+ # 2 =>
+ # {slot_size: 128,
+ # 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},
+ # 3 =>
+ # {slot_size: 256,
+ # 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},
+ # 4 =>
+ # {slot_size: 512,
+ # 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},
+ # 5 =>
+ # {slot_size: 1024,
+ # 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, 5]
+ #
+ # 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(3)
+ # # =>
+ # {slot_size: 256,
+ # 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(3, :slot_size) # => 256
+ #
+ # 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.
#
- # Returns information for memory pools in the GC.
+ def self.stat_heap heap_name = nil, hash_or_key = nil
+ Primitive.gc_stat_heap heap_name, hash_or_key
+ end
+
+ # call-seq:
+ # GC.config -> hash
+ # GC.config(hash_to_merge) -> hash
#
- # If the first optional argument, +heap_name+, is passed in and not +nil+, it
- # returns a +Hash+ containing information about the particular memory pool.
- # Otherwise, it will return a +Hash+ with memory pool names as keys and
- # a +Hash+ containing information about the memory pool as values.
+ # This method is implementation-specific to CRuby.
#
- # If the second optional argument, +hash_or_key+, is given as +Hash+, it will
- # be overwritten and returned. This is intended to avoid the probe effect.
+ # Sets or gets information about the current \GC configuration.
#
- # If both optional arguments are passed in and the second optional argument is
- # a symbol, it will return a +Numeric+ of the value for the particular memory
- # pool.
+ # Configuration parameters are \GC implementation-specific and may change without notice.
#
- # On CRuby, +heap_name+ is of the type +Integer+ but may be of type +String+
- # on other implementations.
+ # With no argument given, returns a hash containing the configuration:
#
- # The contents of the hash are implementation specific and may change in
- # the future without notice.
+ # GC.config
+ # # => {rgengc_allow_full_mark: true, implementation: "default"}
#
- # If the optional argument, hash, is given, it is overwritten and returned.
+ # With argument +hash_to_merge+ given,
+ # merges that hash into the stored configuration hash;
+ # ignores unknown hash keys;
+ # returns the configuration hash:
#
- # This method is only expected to work on CRuby.
- def self.stat_heap heap_name = nil, hash_or_key = nil
- Primitive.gc_stat_heap heap_name, hash_or_key
- end
-
- # call-seq:
- # GC.latest_gc_info -> {:gc_by=>:newobj}
- # GC.latest_gc_info(hash) -> hash
- # GC.latest_gc_info(:major_by) -> :malloc
+ # 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"}
#
- # Returns information about the most recent garbage collection.
+ # <b>All-Implementations Configuration</b>
#
- # If the optional argument, hash, is given,
- # it is overwritten and returned.
- # This is intended to avoid probe effect.
- def self.latest_gc_info hash_or_key = nil
- Primitive.gc_latest_gc_info hash_or_key
- end
+ # The single read-only entry for all implementations is:
+ #
+ # - +:implementation+:
+ # the string name of the implementation;
+ # for the Ruby default implementation, <tt>'default'</tt>.
+ #
+ # <b>Implementation-Specific Configuration</b>
+ #
+ # 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 = 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
- if respond_to?(:compact)
- # call-seq:
- # 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: nil, double_heap: false, expand_heap: false)
- Primitive.gc_verify_compaction_references(double_heap, expand_heap, toward == :empty)
+ Primitive.gc_config_set hash
+ elsif hash != nil
+ raise ArgumentError
end
+
+ Primitive.gc_config_get
end
# call-seq:
- # GC.using_rvargc? -> true or false
+ # 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}
#
- # Returns true if using experimental feature Variable Width Allocation, false
- # otherwise.
- def self.using_rvargc? # :nodoc:
- GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] > 1
- end
+ 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
# call-seq:
- # GC.measure_total_time = true/false
+ # 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
#
- # Enable to measure GC time.
- # You can get the result with <tt>GC.stat(:time)</tt>.
- # Note that GC time measurement can cause some performance overhead.
+ # Note that when enabled, total time measurement affects performance.
def self.measure_total_time=(flag)
Primitive.cstmt! %{
- rb_objspace.flags.measure_gc = RTEST(flag) ? TRUE : FALSE;
+ rb_gc_impl_set_measure_total_time(rb_gc_get_objspace(), flag);
return flag;
}
end
# call-seq:
- # GC.measure_total_time -> true/false
+ # GC.measure_total_time -> true or false
#
- # Return measure_total_time flag (default: +true+).
- # Note that measurement can affect the application performance.
+ # Returns the setting for \GC total time measurement;
+ # the initial setting is +true+.
+ # See GC.total_time.
def self.measure_total_time
Primitive.cexpr! %{
- RBOOL(rb_objspace.flags.measure_gc)
+ RBOOL(rb_gc_impl_get_measure_total_time(rb_gc_get_objspace()))
}
end
# call-seq:
- # GC.total_time -> int
+ # 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
#
- # Return measured GC total time in nano seconds.
def self.total_time
Primitive.cexpr! %{
- ULL2NUM(rb_objspace.profile.total_time_ns)
+ ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace()))
}
end
end
module ObjectSpace
+ # Alias of GC.start
def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
end