[ruby/irb] Change debug test workaround only enabled when output is
[ruby.git] / gc.rb
blob880aa464753697536e9e961e0668676f87907578
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   # Initiates garbage collection, even if manually disabled.
14   #
15   # The +full_mark+ keyword argument determines whether or not to perform a
16   # major garbage collection cycle. When set to +true+, a major garbage
17   # collection cycle is ran, meaning all objects are marked. When set to
18   # +false+, a minor garbage collection cycle is ran, meaning only young
19   # objects are marked.
20   #
21   # The +immediate_mark+ keyword argument determines whether or not to perform
22   # incremental marking. When set to +true+, marking is completed during the
23   # call to this method. When set to +false+, marking is performed in steps
24   # that is interleaved with future Ruby code execution, so marking might not
25   # be completed during this method call. Note that if +full_mark+ is +false+
26   # then marking will always be immediate, regardless of the value of
27   # +immediate_mark+.
28   #
29   # The +immediate_sweep+ keyword argument determines whether or not to defer
30   # sweeping (using lazy sweep). When set to +false+, sweeping is performed in
31   # steps that is interleaved with future Ruby code execution, so sweeping might
32   # not be completed during this method call. When set to +true+, sweeping is
33   # completed during the call to this method.
34   #
35   # Note: These keyword arguments are implementation and version dependent. They
36   # are not guaranteed to be future-compatible, and may be ignored if the
37   # underlying implementation does not support them.
38   def self.start full_mark: true, immediate_mark: true, immediate_sweep: true
39     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
40   end
42   # Alias of GC.start
43   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
44     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
45   end
47   #  call-seq:
48   #     GC.enable    -> true or false
49   #
50   #  Enables garbage collection, returning +true+ if garbage
51   #  collection was previously disabled.
52   #
53   #     GC.disable   #=> false
54   #     GC.enable    #=> true
55   #     GC.enable    #=> false
56   #
57   def self.enable
58     Primitive.gc_enable
59   end
61   #  call-seq:
62   #     GC.disable    -> true or false
63   #
64   #  Disables garbage collection, returning +true+ if garbage
65   #  collection was already disabled.
66   #
67   #     GC.disable   #=> false
68   #     GC.disable   #=> true
69   def self.disable
70     Primitive.gc_disable
71   end
73   #  call-seq:
74   #    GC.stress            -> integer, true or false
75   #
76   #  Returns current status of \GC stress mode.
77   def self.stress
78     Primitive.gc_stress_get
79   end
81   #  call-seq:
82   #    GC.stress = flag          -> flag
83   #
84   #  Updates the \GC stress mode.
85   #
86   #  When stress mode is enabled, the \GC is invoked at every \GC opportunity:
87   #  all memory and object allocations.
88   #
89   #  Enabling stress mode will degrade performance, it is only for debugging.
90   #
91   #  flag can be true, false, or an integer bit-ORed following flags.
92   #    0x01:: no major GC
93   #    0x02:: no immediate sweep
94   #    0x04:: full mark after malloc/calloc/realloc
95   def self.stress=(flag)
96     Primitive.gc_stress_set_m flag
97   end
99   #  call-seq:
100   #     GC.count -> Integer
101   #
102   #  The number of times \GC occurred.
103   #
104   #  It returns the number of times \GC occurred since the process started.
105   def self.count
106     Primitive.gc_count
107   end
109   #  call-seq:
110   #     GC.stat -> Hash
111   #     GC.stat(hash) -> Hash
112   #     GC.stat(:key) -> Numeric
113   #
114   #  Returns a Hash containing information about the \GC.
115   #
116   #  The contents of the hash are implementation specific and may change in
117   #  the future without notice.
118   #
119   #  The hash includes information about internal statistics about \GC such as:
120   #
121   #  [count]
122   #    The total number of garbage collections ran since application start
123   #    (count includes both minor and major garbage collections)
124   #  [time]
125   #    The total time spent in garbage collections (in milliseconds)
126   #  [heap_allocated_pages]
127   #    The total number of +:heap_eden_pages+ + +:heap_tomb_pages+
128   #  [heap_sorted_length]
129   #    The number of pages that can fit into the buffer that holds references to
130   #    all pages
131   #  [heap_allocatable_pages]
132   #    The total number of pages the application could allocate without additional \GC
133   #  [heap_available_slots]
134   #    The total number of slots in all +:heap_allocated_pages+
135   #  [heap_live_slots]
136   #    The total number of slots which contain live objects
137   #  [heap_free_slots]
138   #    The total number of slots which do not contain live objects
139   #  [heap_final_slots]
140   #    The total number of slots with pending finalizers to be run
141   #  [heap_marked_slots]
142   #    The total number of objects marked in the last \GC
143   #  [heap_eden_pages]
144   #    The total number of pages which contain at least one live slot
145   #  [heap_tomb_pages]
146   #    The total number of pages which do not contain any live slots
147   #  [total_allocated_pages]
148   #    The cumulative number of pages allocated since application start
149   #  [total_freed_pages]
150   #    The cumulative number of pages freed since application start
151   #  [total_allocated_objects]
152   #    The cumulative number of objects allocated since application start
153   #  [total_freed_objects]
154   #    The cumulative number of objects freed since application start
155   #  [malloc_increase_bytes]
156   #    Amount of memory allocated on the heap for objects. Decreased by any \GC
157   #  [malloc_increase_bytes_limit]
158   #    When +:malloc_increase_bytes+ crosses this limit, \GC is triggered
159   #  [minor_gc_count]
160   #    The total number of minor garbage collections run since process start
161   #  [major_gc_count]
162   #    The total number of major garbage collections run since process start
163   #  [compact_count]
164   #    The total number of compactions run since process start
165   #  [read_barrier_faults]
166   #    The total number of times the read barrier was triggered during
167   #    compaction
168   #  [total_moved_objects]
169   #    The total number of objects compaction has moved
170   #  [remembered_wb_unprotected_objects]
171   #    The total number of objects without write barriers
172   #  [remembered_wb_unprotected_objects_limit]
173   #    When +:remembered_wb_unprotected_objects+ crosses this limit,
174   #    major \GC is triggered
175   #  [old_objects]
176   #    Number of live, old objects which have survived at least 3 garbage collections
177   #  [old_objects_limit]
178   #    When +:old_objects+ crosses this limit, major \GC is triggered
179   #  [oldmalloc_increase_bytes]
180   #    Amount of memory allocated on the heap for objects. Decreased by major \GC
181   #  [oldmalloc_increase_bytes_limit]
182   #    When +:old_malloc_increase_bytes+ crosses this limit, major \GC is triggered
183   #
184   #  If the optional argument, hash, is given,
185   #  it is overwritten and returned.
186   #  This is intended to avoid probe effect.
187   #
188   #  This method is only expected to work on CRuby.
189   def self.stat hash_or_key = nil
190     Primitive.gc_stat hash_or_key
191   end
193   # call-seq:
194   #    GC.stat_heap -> Hash
195   #    GC.stat_heap(nil, hash) -> Hash
196   #    GC.stat_heap(heap_name) -> Hash
197   #    GC.stat_heap(heap_name, hash) -> Hash
198   #    GC.stat_heap(heap_name, :key) -> Numeric
199   #
200   # Returns information for heaps in the \GC.
201   #
202   # If the first optional argument, +heap_name+, is passed in and not +nil+, it
203   # returns a +Hash+ containing information about the particular heap.
204   # Otherwise, it will return a +Hash+ with heap names as keys and
205   # a +Hash+ containing information about the heap as values.
206   #
207   # If the second optional argument, +hash_or_key+, is given as +Hash+, it will
208   # be overwritten and returned. This is intended to avoid the probe effect.
209   #
210   # If both optional arguments are passed in and the second optional argument is
211   # a symbol, it will return a +Numeric+ of the value for the particular heap.
212   #
213   # On CRuby, +heap_name+ is of the type +Integer+ but may be of type +String+
214   # on other implementations.
215   #
216   # The contents of the hash are implementation specific and may change in
217   # the future without notice.
218   #
219   # If the optional argument, hash, is given, it is overwritten and returned.
220   #
221   # This method is only expected to work on CRuby.
222   #
223   # The hash includes the following keys about the internal information in
224   # the \GC:
225   #
226   # [slot_size]
227   #   The slot size of the heap in bytes.
228   # [heap_allocatable_pages]
229   #   The number of pages that can be allocated without triggering a new
230   #   garbage collection cycle.
231   # [heap_eden_pages]
232   #   The number of pages in the eden heap.
233   # [heap_eden_slots]
234   #   The total number of slots in all of the pages in the eden heap.
235   # [heap_tomb_pages]
236   #   The number of pages in the tomb heap. The tomb heap only contains pages
237   #   that do not have any live objects.
238   # [heap_tomb_slots]
239   #   The total number of slots in all of the pages in the tomb heap.
240   # [total_allocated_pages]
241   #   The total number of pages that have been allocated in the heap.
242   # [total_freed_pages]
243   #   The total number of pages that have been freed and released back to the
244   #   system in the heap.
245   # [force_major_gc_count]
246   #   The number of times major garbage collection cycles this heap has forced
247   #   to start due to running out of free slots.
248   # [force_incremental_marking_finish_count]
249   #   The number of times this heap has forced incremental marking to complete
250   #   due to running out of pooled slots.
251   #
252   def self.stat_heap heap_name = nil, hash_or_key = nil
253     Primitive.gc_stat_heap heap_name, hash_or_key
254   end
256   # call-seq:
257   #     GC.latest_gc_info -> hash
258   #     GC.latest_gc_info(hash) -> hash
259   #     GC.latest_gc_info(:major_by) -> :malloc
260   #
261   # Returns information about the most recent garbage collection.
262   #
263   # If the optional argument, hash, is given,
264   # it is overwritten and returned.
265   # This is intended to avoid probe effect.
266   def self.latest_gc_info hash_or_key = nil
267     Primitive.gc_latest_gc_info hash_or_key
268   end
270   if respond_to?(:compact)
271     # call-seq:
272     #    GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
273     #
274     # Verify compaction reference consistency.
275     #
276     # This method is implementation specific.  During compaction, objects that
277     # were moved are replaced with T_MOVED objects.  No object should have a
278     # reference to a T_MOVED object after compaction.
279     #
280     # This function expands the heap to ensure room to move all objects,
281     # compacts the heap to make sure everything moves, updates all references,
282     # then performs a full \GC.  If any object contains a reference to a T_MOVED
283     # object, that object should be pushed on the mark stack, and will
284     # make a SEGV.
285     def self.verify_compaction_references(toward: nil, double_heap: false, expand_heap: false)
286       Primitive.gc_verify_compaction_references(double_heap, expand_heap, toward == :empty)
287     end
288   end
290   # call-seq:
291   #    GC.measure_total_time = true/false
292   #
293   # Enable to measure \GC time.
294   # You can get the result with <tt>GC.stat(:time)</tt>.
295   # Note that \GC time measurement can cause some performance overhead.
296   def self.measure_total_time=(flag)
297     Primitive.cstmt! %{
298       rb_objspace.flags.measure_gc = RTEST(flag) ? TRUE : FALSE;
299       return flag;
300     }
301   end
303   # call-seq:
304   #    GC.measure_total_time -> true/false
305   #
306   # Return measure_total_time flag (default: +true+).
307   # Note that measurement can affect the application performance.
308   def self.measure_total_time
309     Primitive.cexpr! %{
310       RBOOL(rb_objspace.flags.measure_gc)
311     }
312   end
314   # call-seq:
315   #    GC.total_time -> int
316   #
317   # Return measured \GC total time in nano seconds.
318   def self.total_time
319     Primitive.cexpr! %{
320       ULL2NUM(rb_objspace.profile.marking_time_ns + rb_objspace.profile.sweeping_time_ns)
321     }
322   end
325 module ObjectSpace
326   # Alias of GC.start
327   def garbage_collect full_mark: true, immediate_mark: true, immediate_sweep: true
328     Primitive.gc_start_internal full_mark, immediate_mark, immediate_sweep, false
329   end
331   module_function :garbage_collect