[ruby/psych] Add support for ruby 3.2 Data objects
[ruby.git] / gc.rb
blobd3bb8db036b1cb3ecc57ac7d8b822b8fdd61f237
1 # for gc.c
3 #  The \GC module provides an interface to Ruby's mark-and-sweep garbage collection mechanism.
5 #  Some of the underlying methods are also available via the ObjectSpace module.
7 #  You may obtain information about the operation of the \GC through GC::Profiler.
8 module GC
10   # Initiates garbage collection, even if manually disabled.
11   #
12   # The +full_mark+ keyword argument determines whether or not to perform a
13   # major garbage collection cycle. When set to +true+, a major garbage
14   # collection cycle is run, meaning all objects are marked. When set to
15   # +false+, a minor garbage collection cycle is run, meaning only young
16   # objects are marked.
17   #
18   # The +immediate_mark+ keyword argument determines whether or not to perform
19   # incremental marking. When set to +true+, marking is completed during the
20   # call to this method. When set to +false+, marking is performed in steps
21   # that are interleaved with future Ruby code execution, so marking might not
22   # be completed during this method call. Note that if +full_mark+ is +false+,
23   # then marking will always be immediate, regardless of the value of
24   # +immediate_mark+.
25   #
26   # The +immediate_sweep+ keyword argument determines whether or not to defer
27   # sweeping (using lazy sweep). When set to +false+, sweeping is performed in
28   # steps that are interleaved with future Ruby code execution, so sweeping might
29   # not be completed during this method call. When set to +true+, sweeping is
30   # completed during the call to this method.
31   #
32   # Note: These keyword arguments are implementation and version-dependent. They
33   # are not guaranteed to be future-compatible and may be ignored if the
34   # underlying implementation does not support them.
35   def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
36     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
37   end
39   # Alias of GC.start
40   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
41     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
42   end
44   # call-seq:
45   #    GC.enable -> true or false
46   #
47   # Enables garbage collection, returning +true+ if garbage
48   # collection was previously disabled.
49   #
50   #    GC.disable   #=> false
51   #    GC.enable    #=> true
52   #    GC.enable    #=> false
53   #
54   def self.enable
55     Primitive.gc_enable
56   end
58   # call-seq:
59   #    GC.disable -> true or false
60   #
61   # Disables garbage collection, returning +true+ if garbage
62   # collection was already disabled.
63   #
64   #    GC.disable   #=> false
65   #    GC.disable   #=> true
66   def self.disable
67     Primitive.gc_disable
68   end
70   # call-seq:
71   #   GC.stress -> integer, true, or false
72   #
73   # Returns the current status of \GC stress mode.
74   def self.stress
75     Primitive.gc_stress_get
76   end
78   # call-seq:
79   #   GC.stress = flag -> flag
80   #
81   # Updates the \GC stress mode.
82   #
83   # When stress mode is enabled, the \GC is invoked at every \GC opportunity:
84   # all memory and object allocations.
85   #
86   # Enabling stress mode will degrade performance; it is only for debugging.
87   #
88   # The flag can be true, false, or an integer bitwise-ORed with the following flags:
89   #   0x01:: no major GC
90   #   0x02:: no immediate sweep
91   #   0x04:: full mark after malloc/calloc/realloc
92   def self.stress=(flag)
93     Primitive.gc_stress_set_m flag
94   end
96   # call-seq:
97   #    GC.count -> Integer
98   #
99   # Returns the number of times \GC has occurred since the process started.
100   def self.count
101     Primitive.gc_count
102   end
104   # call-seq:
105   #    GC.stat -> Hash
106   #    GC.stat(hash) -> Hash
107   #    GC.stat(:key) -> Numeric
108   #
109   # Returns a Hash containing information about the \GC.
110   #
111   # The contents of the hash are implementation-specific and may change in
112   # the future without notice.
113   #
114   # The hash includes internal statistics about \GC such as:
115   #
116   # [count]
117   #   The total number of garbage collections run since application start
118   #   (count includes both minor and major garbage collections)
119   # [time]
120   #   The total time spent in garbage collections (in milliseconds)
121   # [heap_allocated_pages]
122   #   The total number of +:heap_eden_pages+ + +:heap_tomb_pages+
123   # [heap_sorted_length]
124   #   The number of pages that can fit into the buffer that holds references to
125   #   all pages
126   # [heap_allocatable_pages]
127   #   The total number of pages the application could allocate without additional \GC
128   # [heap_available_slots]
129   #   The total number of slots in all +:heap_allocated_pages+
130   # [heap_live_slots]
131   #   The total number of slots which contain live objects
132   # [heap_free_slots]
133   #   The total number of slots which do not contain live objects
134   # [heap_final_slots]
135   #   The total number of slots with pending finalizers to be run
136   # [heap_marked_slots]
137   #   The total number of objects marked in the last \GC
138   # [heap_eden_pages]
139   #   The total number of pages which contain at least one live slot
140   # [heap_tomb_pages]
141   #   The total number of pages which do not contain any live slots
142   # [total_allocated_pages]
143   #   The cumulative number of pages allocated since application start
144   # [total_freed_pages]
145   #   The cumulative number of pages freed since application start
146   # [total_allocated_objects]
147   #   The cumulative number of objects allocated since application start
148   # [total_freed_objects]
149   #   The cumulative number of objects freed since application start
150   # [malloc_increase_bytes]
151   #   Amount of memory allocated on the heap for objects. Decreased by any \GC
152   # [malloc_increase_bytes_limit]
153   #   When +:malloc_increase_bytes+ crosses this limit, \GC is triggered
154   # [minor_gc_count]
155   #   The total number of minor garbage collections run since process start
156   # [major_gc_count]
157   #   The total number of major garbage collections run since process start
158   # [compact_count]
159   #   The total number of compactions run since process start
160   # [read_barrier_faults]
161   #   The total number of times the read barrier was triggered during
162   #   compaction
163   # [total_moved_objects]
164   #   The total number of objects compaction has moved
165   # [remembered_wb_unprotected_objects]
166   #   The total number of objects without write barriers
167   # [remembered_wb_unprotected_objects_limit]
168   #   When +:remembered_wb_unprotected_objects+ crosses this limit,
169   #   major \GC is triggered
170   # [old_objects]
171   #   Number of live, old objects which have survived at least 3 garbage collections
172   # [old_objects_limit]
173   #   When +:old_objects+ crosses this limit, major \GC is triggered
174   # [oldmalloc_increase_bytes]
175   #   Amount of memory allocated on the heap for objects. Decreased by major \GC
176   # [oldmalloc_increase_bytes_limit]
177   #   When +:oldmalloc_increase_bytes+ crosses this limit, major \GC is triggered
178   #
179   # If the optional argument, hash, is given,
180   # it is overwritten and returned.
181   # This is intended to avoid the probe effect.
182   #
183   # This method is only expected to work on CRuby.
184   def self.stat hash_or_key = nil
185     Primitive.gc_stat hash_or_key
186   end
188   # call-seq:
189   #    GC.stat_heap -> Hash
190   #    GC.stat_heap(nil, hash) -> Hash
191   #    GC.stat_heap(heap_name) -> Hash
192   #    GC.stat_heap(heap_name, hash) -> Hash
193   #    GC.stat_heap(heap_name, :key) -> Numeric
194   #
195   # Returns information for heaps in the \GC.
196   #
197   # If the first optional argument, +heap_name+, is passed in and not +nil+, it
198   # returns a +Hash+ containing information about the particular heap.
199   # Otherwise, it will return a +Hash+ with heap names as keys and
200   # a +Hash+ containing information about the heap as values.
201   #
202   # If the second optional argument, +hash_or_key+, is given as a +Hash+, it will
203   # be overwritten and returned. This is intended to avoid the probe effect.
204   #
205   # If both optional arguments are passed in and the second optional argument is
206   # a symbol, it will return a +Numeric+ value for the particular heap.
207   #
208   # On CRuby, +heap_name+ is of the type +Integer+ but may be of type +String+
209   # on other implementations.
210   #
211   # The contents of the hash are implementation-specific and may change in
212   # the future without notice.
213   #
214   # If the optional argument, hash, is given, it is overwritten and returned.
215   #
216   # This method is only expected to work on CRuby.
217   #
218   # The hash includes the following keys about the internal information in
219   # the \GC:
220   #
221   # [slot_size]
222   #   The slot size of the heap in bytes.
223   # [heap_allocatable_pages]
224   #   The number of pages that can be allocated without triggering a new
225   #   garbage collection cycle.
226   # [heap_eden_pages]
227   #   The number of pages in the eden heap.
228   # [heap_eden_slots]
229   #   The total number of slots in all of the pages in the eden heap.
230   # [heap_tomb_pages]
231   #   The number of pages in the tomb heap. The tomb heap only contains pages
232   #   that do not have any live objects.
233   # [heap_tomb_slots]
234   #   The total number of slots in all of the pages in the tomb heap.
235   # [total_allocated_pages]
236   #   The total number of pages that have been allocated in the heap.
237   # [total_freed_pages]
238   #   The total number of pages that have been freed and released back to the
239   #   system in the heap.
240   # [force_major_gc_count]
241   #   The number of times this heap has forced major garbage collection cycles
242   #   to start due to running out of free slots.
243   # [force_incremental_marking_finish_count]
244   #   The number of times this heap has forced incremental marking to complete
245   #   due to running out of pooled slots.
246   #
247   def self.stat_heap heap_name = nil, hash_or_key = nil
248     Primitive.gc_stat_heap heap_name, hash_or_key
249   end
251   # call-seq:
252   #     GC.config -> hash
253   #     GC.config(hash) -> hash
254   #
255   # Sets or gets information about the current \GC config.
256   #
257   # Configuration parameters are \GC implementation-specific and may change
258   # without notice.
259   #
260   # This method can be called without parameters to retrieve the current config
261   # as a +Hash+ with +Symbol+ keys.
262   #
263   # This method can also be called with a +Hash+ argument to assign values to
264   # valid config keys. Config keys missing from the passed +Hash+ will be left
265   # unmodified.
266   #
267   # If a key/value pair is passed to this function that does not correspond to
268   # a valid config key for the \GC implementation being used, no config will be
269   # updated, the key will be present in the returned Hash, and its value will
270   # be +nil+. This is to facilitate easy migration between \GC implementations.
271   #
272   # In both call-seqs, the return value of <code>GC.config</code> will be a +Hash+
273   # containing the most recent full configuration, i.e., all keys and values
274   # defined by the specific \GC implementation being used. In the case of a
275   # config update, the return value will include the new values being updated.
276   #
277   # This method is only expected to work on CRuby.
278   #
279   # === \GC Implementation independent values
280   #
281   # The <code>GC.config</code> hash can also contain keys that are global and
282   # read-only. These keys are not specific to any one \GC library implementation
283   # and attempting to write to them will raise +ArgumentError+.
284   #
285   # There is currently only one global, read-only key:
286   #
287   # [implementation]
288   #    Returns a +String+ containing the name of the currently loaded \GC library,
289   #    if one has been loaded using +RUBY_GC_LIBRARY+, and "default" in all other
290   #    cases
291   #
292   # === \GC Implementation specific values
293   #
294   # \GC libraries are expected to document their own configuration. Valid keys
295   # for Ruby's default \GC implementation are:
296   #
297   # [rgengc_allow_full_mark]
298   #   Controls whether the \GC is allowed to run a full mark (young & old objects).
299   #
300   #   When +true+, \GC interleaves major and minor collections. This is the default. \GC
301   #   will function as intended.
302   #
303   #   When +false+, the \GC will never trigger a full marking cycle unless
304   #   explicitly requested by user code. Instead, only a minor mark will run—
305   #   only young objects will be marked. When the heap space is exhausted, new
306   #   pages will be allocated immediately instead of running a full mark.
307   #
308   #   A flag will be set to notify that a full mark has been
309   #   requested. This flag is accessible using
310   #   <code>GC.latest_gc_info(:need_major_by)</code>
311   #
312   #   The user can trigger a major collection at any time using
313   #   <code>GC.start(full_mark: true)</code>
314   #
315   #   When +false+, Young to Old object promotion is disabled. For performance
316   #   reasons, it is recommended to warm up an application using +Process.warmup+
317   #   before setting this parameter to +false+.
318   def self.config hash = nil
319     return Primitive.gc_config_get unless hash
321     if(Primitive.cexpr!("RBOOL(RB_TYPE_P(hash, T_HASH))"))
322       if hash.include?(:implementation)
323         raise ArgumentError, 'Attempting to set read-only key "Implementation"'
324       end
326       Primitive.gc_config_set hash
327     else
328       raise ArgumentError
329     end
330   end
332   # call-seq:
333   #     GC.latest_gc_info -> hash
334   #     GC.latest_gc_info(hash) -> hash
335   #     GC.latest_gc_info(key) -> value
336   #
337   # Returns information about the most recent garbage collection.
338   #
339   # If the argument +hash+ is given and is a Hash object,
340   # it is overwritten and returned.
341   # This is intended to avoid the probe effect.
342   #
343   # If the argument +key+ is given and is a Symbol object,
344   # it returns the value associated with the key.
345   # This is equivalent to <tt>GC.latest_gc_info[key]</tt>.
346   def self.latest_gc_info hash_or_key = nil
347     if hash_or_key == nil
348       hash_or_key = {}
349     elsif Primitive.cexpr!("RBOOL(!SYMBOL_P(hash_or_key) && !RB_TYPE_P(hash_or_key, T_HASH))")
350       raise TypeError, "non-hash or symbol given"
351     end
353     Primitive.cstmt! %{
354       return rb_gc_latest_gc_info(hash_or_key);
355     }
356   end
358   # call-seq:
359   #    GC.measure_total_time = true/false
360   #
361   # Enables measuring \GC time.
362   # You can get the result with <tt>GC.stat(:time)</tt>.
363   # Note that \GC time measurement can cause some performance overhead.
364   def self.measure_total_time=(flag)
365     Primitive.cstmt! %{
366       rb_gc_impl_set_measure_total_time(rb_gc_get_objspace(), flag);
367       return flag;
368     }
369   end
371   # call-seq:
372   #    GC.measure_total_time -> true/false
373   #
374   # Returns the measure_total_time flag (default: +true+).
375   # Note that measurement can affect the application's performance.
376   def self.measure_total_time
377     Primitive.cexpr! %{
378       RBOOL(rb_gc_impl_get_measure_total_time(rb_gc_get_objspace()))
379     }
380   end
382   # call-seq:
383   #    GC.total_time -> int
384   #
385   # Returns the measured \GC total time in nanoseconds.
386   def self.total_time
387     Primitive.cexpr! %{
388       ULL2NUM(rb_gc_impl_get_total_time(rb_gc_get_objspace()))
389     }
390   end
393 module ObjectSpace
394   # Alias of GC.start
395   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
396     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
397   end
399   module_function :garbage_collect