* 2022-01-18 [ci skip]
[ruby-80x24.org.git] / gc.rb
blobe9fb8f883b6bc2fd47798f5c35cfdb531205d183
1 # for gc.c
3 #  The GC module provides an interface to Ruby's mark and
4 #  sweep garbage collection mechanism.
6 #  Some of the underlying methods are also available via the ObjectSpace
7 #  module.
9 #  You may obtain information about the operation of the GC through
10 #  GC::Profiler.
11 module GC
13   #  call-seq:
14   #     GC.start                     -> nil
15   #     ObjectSpace.garbage_collect  -> nil
16   #     include GC; garbage_collect  -> nil
17   #     GC.start(full_mark: true, immediate_sweep: true)           -> nil
18   #     ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
19   #     include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
20   #
21   #  Initiates garbage collection, even if manually disabled.
22   #
23   #  This method is defined with keyword arguments that default to true:
24   #
25   #     def GC.start(full_mark: true, immediate_sweep: true); end
26   #
27   #  Use full_mark: false to perform a minor GC.
28   #  Use immediate_sweep: false to defer sweeping (use lazy sweep).
29   #
30   #  Note: These keyword arguments are implementation and version dependent. They
31   #  are not guaranteed to be future-compatible, and may be ignored if the
32   #  underlying implementation does not support them.
33   def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
34     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
35   end
37   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
38     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
39   end
41   #  call-seq:
42   #     GC.auto_compact    -> true or false
43   #
44   #  Returns whether or not automatic compaction has been enabled.
45   #
46   def self.auto_compact
47     Primitive.gc_get_auto_compact
48   end
50   #  call-seq:
51   #     GC.auto_compact = flag
52   #
53   #  Updates automatic compaction mode.
54   #
55   #  When enabled, the compactor will execute on every major collection.
56   #
57   #  Enabling compaction will degrade performance on major collections.
58   def self.auto_compact=(flag)
59     Primitive.gc_set_auto_compact(flag)
60   end
62   #  call-seq:
63   #     GC.enable    -> true or false
64   #
65   #  Enables garbage collection, returning +true+ if garbage
66   #  collection was previously disabled.
67   #
68   #     GC.disable   #=> false
69   #     GC.enable    #=> true
70   #     GC.enable    #=> false
71   #
72   def self.enable
73     Primitive.gc_enable
74   end
76   #  call-seq:
77   #     GC.disable    -> true or false
78   #
79   #  Disables garbage collection, returning +true+ if garbage
80   #  collection was already disabled.
81   #
82   #     GC.disable   #=> false
83   #     GC.disable   #=> true
84   def self.disable
85     Primitive.gc_disable
86   end
88   #  call-seq:
89   #    GC.stress            -> integer, true or false
90   #
91   #  Returns current status of GC stress mode.
92   def self.stress
93     Primitive.gc_stress_get
94   end
96   #  call-seq:
97   #    GC.stress = flag          -> flag
98   #
99   #  Updates the GC stress mode.
100   #
101   #  When stress mode is enabled, the GC is invoked at every GC opportunity:
102   #  all memory and object allocations.
103   #
104   #  Enabling stress mode will degrade performance, it is only for debugging.
105   #
106   #  flag can be true, false, or an integer bit-ORed following flags.
107   #    0x01:: no major GC
108   #    0x02:: no immediate sweep
109   #    0x04:: full mark after malloc/calloc/realloc
110   def self.stress=(flag)
111     Primitive.gc_stress_set_m flag
112   end
114   #  call-seq:
115   #     GC.count -> Integer
116   #
117   #  The number of times GC occurred.
118   #
119   #  It returns the number of times GC occurred since the process started.
120   def self.count
121     Primitive.gc_count
122   end
124   #  call-seq:
125   #     GC.stat -> Hash
126   #     GC.stat(hash) -> Hash
127   #     GC.stat(:key) -> Numeric
128   #
129   #  Returns a Hash containing information about the GC.
130   #
131   #  The contents of the hash are implementation specific and may change in
132   #  the future without notice.
133   #
134   #  The hash includes information about internal statistics about GC such as:
135   #
136   #  [count]
137   #    The total number of garbage collections ran since application start
138   #    (count includes both minor and major garbage collections)
139   #  [time]
140   #    The total time spent in garbage collections (in milliseconds)
141   #  [heap_allocated_pages]
142   #    The total number of `:heap_eden_pages` + `:heap_tomb_pages`
143   #  [heap_sorted_length]
144   #    The number of pages that can fit into the buffer that holds references to
145   #    all pages
146   #  [heap_allocatable_pages]
147   #    The total number of pages the application could allocate without additional GC
148   #  [heap_available_slots]
149   #    The total number of slots in all `:heap_allocated_pages`
150   #  [heap_live_slots]
151   #    The total number of slots which contain live objects
152   #  [heap_free_slots]
153   #    The total number of slots which do not contain live objects
154   #  [heap_final_slots]
155   #    The total number of slots with pending finalizers to be run
156   #  [heap_marked_slots]
157   #    The total number of objects marked in the last GC
158   #  [heap_eden_pages]
159   #    The total number of pages which contain at least one live slot
160   #  [heap_tomb_pages]
161   #    The total number of pages which do not contain any live slots
162   #  [total_allocated_pages]
163   #    The cumulative number of pages allocated since application start
164   #  [total_freed_pages]
165   #    The cumulative number of pages freed since application start
166   #  [total_allocated_objects]
167   #    The cumulative number of objects allocated since application start
168   #  [total_freed_objects]
169   #    The cumulative number of objects freed since application start
170   #  [malloc_increase_bytes]
171   #    Amount of memory allocated on the heap for objects. Decreased by any GC
172   #  [malloc_increase_bytes_limit]
173   #    When `:malloc_increase_bytes` crosses this limit, GC is triggered
174   #  [minor_gc_count]
175   #    The total number of minor garbage collections run since process start
176   #  [major_gc_count]
177   #    The total number of major garbage collections run since process start
178   #  [compact_count]
179   #    The total number of compactions run since process start
180   #  [read_barrier_faults]
181   #    The total number of times the read barrier was triggered during
182   #    compaction
183   #  [total_moved_objects]
184   #    The total number of objects compaction has moved
185   #  [remembered_wb_unprotected_objects]
186   #    The total number of objects without write barriers
187   #  [remembered_wb_unprotected_objects_limit]
188   #    When `:remembered_wb_unprotected_objects` crosses this limit,
189   #    major GC is triggered
190   #  [old_objects]
191   #    Number of live, old objects which have survived at least 3 garbage collections
192   #  [old_objects_limit]
193   #    When `:old_objects` crosses this limit, major GC is triggered
194   #  [oldmalloc_increase_bytes]
195   #    Amount of memory allocated on the heap for objects. Decreased by major GC
196   #  [oldmalloc_increase_bytes_limit]
197   #    When `:old_malloc_increase_bytes` crosses this limit, major GC is triggered
198   #
199   #  If the optional argument, hash, is given,
200   #  it is overwritten and returned.
201   #  This is intended to avoid probe effect.
202   #
203   #  This method is only expected to work on CRuby.
204   def self.stat hash_or_key = nil
205     Primitive.gc_stat hash_or_key
206   end
208   # call-seq:
209   #    GC.stat_heap -> Hash
210   #    GC.stat_heap(nil, hash) -> Hash
211   #    GC.stat_heap(heap_name) -> Hash
212   #    GC.stat_heap(heap_name, hash) -> Hash
213   #    GC.stat_heap(heap_name, :key) -> Numeric
214   #
215   # Returns information for memory pools in the GC.
216   #
217   # If the first optional argument, +heap_name+, is passed in and not +nil+, it
218   # returns a +Hash+ containing information about the particular memory pool.
219   # Otherwise, it will return a +Hash+ with memory pool names as keys and
220   # a +Hash+ containing information about the memory pool as values.
221   #
222   # If the second optional argument, +hash_or_key+, is given as +Hash+, it will
223   # be overwritten and returned. This is intended to avoid the probe effect.
224   #
225   # If both optional arguments are passed in and the second optional argument is
226   # a symbol, it will return a +Numeric+ of the value for the particular memory
227   # pool.
228   #
229   # On CRuby, +heap_name+ is of the type +Integer+ but may be of type +String+
230   # on other implementations.
231   #
232   # The contents of the hash are implementation specific and may change in
233   # the future without notice.
234   #
235   # If the optional argument, hash, is given, it is overwritten and returned.
236   #
237   # This method is only expected to work on CRuby.
238   def self.stat_heap heap_name = nil, hash_or_key = nil
239     Primitive.gc_stat_heap heap_name, hash_or_key
240   end
242   #  call-seq:
243   #     GC.latest_gc_info -> {:gc_by=>:newobj}
244   #     GC.latest_gc_info(hash) -> hash
245   #     GC.latest_gc_info(:major_by) -> :malloc
246   #
247   #  Returns information about the most recent garbage collection.
248   #
249   # If the optional argument, hash, is given,
250   # it is overwritten and returned.
251   # This is intended to avoid probe effect.
252   def self.latest_gc_info hash_or_key = nil
253     Primitive.gc_latest_gc_info hash_or_key
254   end
256   #  call-seq:
257   #     GC.latest_compact_info -> {:considered=>{:T_CLASS=>11}, :moved=>{:T_CLASS=>11}}
258   #
259   #  Returns information about object moved in the most recent GC compaction.
260   #
261   # The returned hash has two keys :considered and :moved.  The hash for
262   # :considered lists the number of objects that were considered for movement
263   # by the compactor, and the :moved hash lists the number of objects that
264   # were actually moved.  Some objects can't be moved (maybe they were pinned)
265   # so these numbers can be used to calculate compaction efficiency.
266   def self.latest_compact_info
267     Primitive.gc_compact_stats
268   end
270   #  call-seq:
271   #     GC.compact
272   #
273   # This function compacts objects together in Ruby's heap.  It eliminates
274   # unused space (or fragmentation) in the heap by moving objects in to that
275   # unused space.  This function returns a hash which contains statistics about
276   # which objects were moved.  See `GC.latest_gc_info` for details about
277   # compaction statistics.
278   #
279   # This method is implementation specific and not expected to be implemented
280   # in any implementation besides MRI.
281   def self.compact
282     Primitive.gc_compact
283   end
285   # call-seq:
286   #    GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
287   #
288   # Verify compaction reference consistency.
289   #
290   # This method is implementation specific.  During compaction, objects that
291   # were moved are replaced with T_MOVED objects.  No object should have a
292   # reference to a T_MOVED object after compaction.
293   #
294   # This function doubles the heap to ensure room to move all objects,
295   # compacts the heap to make sure everything moves, updates all references,
296   # then performs a full GC.  If any object contains a reference to a T_MOVED
297   # object, that object should be pushed on the mark stack, and will
298   # make a SEGV.
299   def self.verify_compaction_references(toward: nil, double_heap: false)
300     Primitive.gc_verify_compaction_references(double_heap, toward == :empty)
301   end
303   # call-seq:
304   #     GC.using_rvargc? -> true or false
305   #
306   # Returns true if using experimental feature Variable Width Allocation, false
307   # otherwise.
308   def self.using_rvargc? # :nodoc:
309     GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] > 1
310   end
313   # call-seq:
314   #    GC.measure_total_time = true/false
315   #
316   # Enable to measure GC time.
317   # You can get the result with <tt>GC.stat(:time)</tt>.
318   # Note that GC time measurement can cause some performance overhead.
319   def self.measure_total_time=(flag)
320     Primitive.cstmt! %{
321       rb_objspace.flags.measure_gc = RTEST(flag) ? TRUE : FALSE;
322       return flag;
323     }
324   end
326   # call-seq:
327   #    GC.measure_total_time -> true/false
328   #
329   # Return measure_total_time flag (default: +true+).
330   # Note that measurement can affect the application performance.
331   def self.measure_total_time
332     Primitive.cexpr! %{
333       RBOOL(rb_objspace.flags.measure_gc)
334     }
335   end
337   # call-seq:
338   #    GC.total_time -> int
339   #
340   # Return measured GC total time in nano seconds.
341   def self.total_time
342     Primitive.cexpr! %{
343       ULL2NUM(rb_objspace.profile.total_time_ns)
344     }
345   end
348 module ObjectSpace
349   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
350     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
351   end
353   module_function :garbage_collect