83 Commits
Author SHA1 Message Date
Matt Valentine-House 01fe91202c Replace GC.stat scope: with a process: keyword
Recently we added some keys to GC.stat in order to measure the GC
performance of Ractor local GC and the associated global GC.

This commit refactors some of those terms: "global" was used in two
places with different meanings which could get confusing.

When it was passed to GC.stat as scope: :global it meant "Give me
aggregate stats for all the GCs running in this process".

Whereas inside the output of GC.stat, global referred to the number of
"global" GCs that are run. That is: stop-the-world GCs that run on
every ractor heap in the process.

Also the global_gc_count that GC.stat reports for a Ractor ignored
global GCs that other Ractors started, even though they swept its heap.

In this commit we fix this confusing behaviour, and make the GC.stat
output more consistent.

We've replaced the scope: parameter to GC.stat with the boolean
process: keyword arg. The default is process: false which means
GC.stat will return stats for the Ractor that executes the code (the
main Ractor if no other Ractors have been created). process: true will
return aggregate stats over all the Ractors in the process (including
dead ones).

Inside GC.stat(process: false), count and global_gc_count now
include every global GC that has swept that Ractor's heap. So Ractor
local gc count == count - global_gc_count.

heap_marked_slots now counts only the marked objects in that Ractor's
own heap. Before, the Ractor that started a global GC counted the
marked objects of every heap, and the other Ractors reported 0.

We also provide a new key global_gc_invocation_count that is the
number of global GCs that have been triggered by the Ractor in question.

We've also moved some keys related to the global page pool out of the
default GC.stat output and into GC.stat(process: true), because they
are process-wide and not Ractor specific.
2026-10-23 17:05:54 +01:00
Matt Valentine-House ee4013b90f Count global GC cycles per Ractor in GC.stat
GC.stat(:global_gc_count) now reports the stop-the-world global cycles
the current Ractor started, instead of mirroring the process-wide count,
so the values can be summed across Ractors. GC.stat(:global_gc_count,
scope: :global) gives the process total, including Ractors that have
since exited.

A global cycle no longer counts as a major GC on the Ractor that started
it, so count == minor_gc_count + major_gc_count + global_gc_count.
2026-10-05 19:08:14 +01:00
Matt Valentine-House 60c206b683 Add global scope to GC.stat 2026-09-25 12:18:01 +01:00
Peter Zhu 3e646aee64 [DOC] Update docs for GC.stat 2026-08-04 08:49:15 -04:00
Peter Zhu f16405da94 [DOC] Improve docs for GC.stress= 2026-08-03 20:45:05 -04:00
Peter Zhu 60c82965ea [DOC] Improve docs for GC.start 2026-08-02 21:12:33 -04:00
Matt Valentine-House c9b7088364 Introduce power-of-two size pools
Replace the RVALUE_SLOT_SIZE-multiplier based pool sizes with explicit
power-of-two (and near-power-of-two) slot sizes. On 64-bit this gives
12 heaps (32, 40, 64, 80, 96, 128, 160, 256, 512, 640, 768, 1024)
instead of 5, providing finer granularity and less internal
fragmentation. On 32-bit the layout is 5 heaps (32, 64, 128, 256, 512).
2026-04-09 13:24:09 +01:00
Nobuyoshi Nakada 5b83468b86 Adjust indent [ci skip] 2026-03-30 21:33:48 +09:00
Matt Valentine-House 0875a0f859 Replace heap_init_slots array with single heap_init_bytes target
Replace per-heap GC_HEAP_INIT_SLOTS with a single GC_HEAP_INIT_BYTES
target.

Instead of allocating a fixed 10k slot budget for each heap to grow
into. This PR gives each heap a fixed 2.5Mb heap growth allowance. This
keeps the overall heap size budget roughly the same, but allows the
smaller pools to grow much larger before more pages are allocated.

```
Heap 0: 10,000 × 40  =   400,000 bytes
Heap 1: 10,000 × 80  =   800,000 bytes
Heap 2: 10,000 × 160 = 1,600,000 bytes
Heap 3: 10,000 × 320 = 3,200,000 bytes
Heap 4: 10,000 × 640 = 6,400,000 bytes

Total:  12,400,000 bytes (50,000 slots)
```

```
Heap 0: 2,621,440 / 40  = 65,536 slots
Heap 1: 2,621,440 / 80  = 32,768 slots
Heap 2: 2,621,440 / 160 = 16,384 slots
Heap 3: 2,621,440 / 320 = 8,192 slots
Heap 4: 2,621,440 / 640 = 4,096 slots

Total:  13,107,200 bytes (126,976 slots)
```
2026-03-30 12:31:55 +01:00
hi 25f277abe4 Fix typos in gc.c and gc.rb 2025-12-09 16:45:38 +09:00
Jean Boussier e057ff333a [Doc] Fix duplicated entry in GC.stat documentation 2025-11-26 18:06:58 +01:00
Jean Boussier c0256d1d5d [DOC] Update GC.stat and GC.stat_heap documentation
I noticed some of the keys have been gone or renamed for a while.
2025-11-17 18:46:32 +00:00
Burdette Lamar ad047459c1 [DOC] Tweaks for GC.stat_heap 2025-08-16 17:08:11 -04:00
BurdetteLamar b0cd89a5b5 [DOC] Tweaks for GC.stress and GC.stress= 2025-08-14 21:51:21 -04:00
Burdette Lamar 12e42f72ae [DOC] Tweaks for GC.stat 2025-08-14 21:47:39 -04:00
BurdetteLamar ff622978d0 [DOC] Tweaks for GC total time methods 2025-08-13 14:42:17 -04:00
Burdette Lamar 7595ac9a9e [DOC] Tweaks for GC.count 2025-08-13 10:53:22 -04:00
BurdetteLamar 31e8a9fced [DOC] Tweaks for GC.latest_gc_info 2025-08-12 17:06:15 -04:00
BurdetteLamar 8b530e1282 [DOC] Tweaks for GC.enable 2025-08-12 17:04:25 -04:00
BurdetteLamar b934f989b9 [DOC] Tweaks for GC.disable 2025-08-12 17:04:06 -04:00
Peter Zhu 428937a536 [DOC] Fix docs for GC.config
After commit 61fff8a, GC.config now returns the same hash for getting and
setting.
2025-08-11 22:14:57 -04:00
Peter Zhu 61fff8a92f Fix return value of setting in GC.config
gc_config_set returned rb_gc_impl_config_get, but gc_config_get also added
the implementation key to the return value. This caused the return value
of GC.config to differ depending on whether the optional hash argument is
provided or not.
2025-08-11 10:20:33 -04:00
BurdetteLamar ad14632095 [DOC] Tweaks for GC.config 2025-08-11 09:24:06 -04:00
BurdetteLamar 62b5fe8984 [DOC] Tweaks for GC.config 2025-08-11 09:24:06 -04:00
Burdette Lamar 52312d53ca [DOC] Tweaks for GC.start (#14093) 2025-08-05 15:58:00 -04:00
Serg Tyatin abd1b700d2 [DOC] Fix description comment typo 2025-02-13 08:53:02 +09:00
Matt Valentine-House aa360c3bee [DOC] Fix to GC.config docs 2024-12-20 19:51:53 +00:00
Matt Valentine-House 07724d7b6f [DOC] Document the :implementation key of GC.config 2024-12-20 19:47:01 +00:00
Stan Lo 4a7ac694e5 Fix grammar errors and typos in gc.rb 2024-11-18 09:04:50 -06:00
Matt Valentine-House 42501015b4 rb_raise when attempting to set the GC implementation name
Instead of silently ignoring the key, we should raise to clearly tell
the user that this key is read-only.
2024-11-14 10:46:36 +00:00
Peter Zhu d9981beb40 [DOC] Improve docs for GC.latest_gc_info 2024-09-19 12:10:27 -04:00
Peter Zhu 984a791d58 [DOC] Escape the word GC in GC.config 2024-09-18 16:47:59 -04:00
Peter Zhu f8e1c93fe1 Move more of GC.latest_gc_info into Ruby 2024-09-18 12:58:05 -04:00
Peter Zhu 5df5eba465 Change rb_gc_impl_get_measure_total_time to return a bool 2024-09-18 10:18:47 -04:00
Peter Zhu 5307c65c76 Make rb_gc_impl_set_measure_total_time return void 2024-09-17 16:35:52 -04:00
Peter Zhu dc61c7fc7d Rename rb_gc_impl_get_profile_total_time to rb_gc_impl_get_total_time 2024-09-17 15:22:43 -04:00
Peter Zhu 2af080bd30 Change rb_gc_impl_get_profile_total_time to return unsigned long long 2024-09-17 15:22:43 -04:00
Matt Valentine-House 3ccc6e0b6a Document GC.config 2024-07-12 14:43:33 +01:00
Matt Valentine-House f543c68e1c Provide GC.config to disable major GC collections
This feature provides a new method `GC.config` that configures internal
GC configuration variables provided by an individual GC implementation.

Implemented in this PR is the option `full_mark`: a boolean value that
will determine whether the Ruby GC is allowed to run a major collection
while the process is running.

It has the following semantics

This feature configures Ruby's GC to only run minor GC's. It's designed
to give users relying on Out of Band GC complete control over when a
major GC is run. Configuring `full_mark: false` does two main things:

* Never runs a Major GC. When the heap runs out of space during a minor
  and when a major would traditionally be run, instead we allocate more
  heap pages, and mark objspace as needing a major GC.
* Don't increment object ages. We don't promote objects during GC, this
  will cause every object to be scanned on every minor. This is an
  intentional trade-off between minor GC's doing more work every time,
  and potentially promoting objects that will then never be GC'd.

The intention behind not aging objects is that users of this feature
should use a preforking web server, or some other method of pre-warming
the oldgen (like Nakayoshi fork)before disabling Majors. That way most
objects that are going to be old will have already been promoted.

This will interleave major and minor GC collections in exactly the same
what that the Ruby GC runs in versions previously to this. This is the
default behaviour.

* This new method has the following extra semantics:
  - `GC.config` with no arguments returns a hash of the keys of the
    currently configured GC
  - `GC.config` with a key pair (eg. `GC.config(full_mark: true)` sets
    the matching config key to the corresponding value and returns the
    entire known config hash, including the new values. If the key does
    not exist, `nil` is returned

* When a minor GC is run, Ruby sets an internal status flag to determine
  whether the next GC will be a major or a minor. When `full_mark:
  false` this flag is ignored and every GC will be a minor.

  This status flag can be accessed at
  `GC.latest_gc_info(:needs_major_by)`. Any value other than `nil` means
  that the next collection would have been a major.

  Thus it's possible to use this feature to check at a predetermined
  time, whether a major GC is necessary and run one if it is. eg. After
  a request has finished processing.

  ```ruby
  if GC.latest_gc_info(:needs_major_by)
    GC.start(full_mark: true)
  end
  ```

[Feature #20443]
2024-07-12 14:43:33 +01:00
Peter Zhu 51bd816517 [Feature #20470] Split GC into gc_impl.c
This commit splits gc.c into two files:

- gc.c now only contains code not specific to Ruby GC. This includes
  code to mark objects (which the GC implementation may choose not to
  use) and wrappers for internal APIs that the implementation may need
  to use (e.g. locking the VM).

- gc_impl.c now contains the implementation of Ruby's GC. This includes
  marking, sweeping, compaction, and statistics. Most importantly,
  gc_impl.c only uses public APIs in Ruby and a limited set of functions
  exposed in gc.c. This allows us to build gc_impl.c independently of
  Ruby and plug Ruby's GC into itself.
2024-07-03 09:03:40 -04:00
Alexander Ross 5efe386c89 [DOC] Fix typo in GC documentation
The documentation for GC.start was incorrect. It said that the
`immediate_sweep` keyword argument would defer sweeping when set to
`true`, but it should have said that it would defer sweeping when set to
`false`.

The commit will also fix the typo "immedate_sweep" to "immediate_sweep".
2024-02-27 11:19:02 +00:00
Nobuyoshi Nakada 9abaf00c07 [DOC] documents of aliased methods 2023-12-18 20:17:43 +09:00
Peter Zhu 0f94e65359 Add stat force_incremental_marking_finish_count
This commit adds key force_incremental_marking_finish_count to
GC.stat_heap. This statistic returns the number of times the size pool
has forced incremental marking to finish due to running out of slots.
2023-08-15 15:18:05 -04:00
Peter Zhu 2f57db6c77 [DOC] Rename "memory pool" to "heap" 2023-08-15 08:54:27 -04:00
Peter Zhu 01f74b2852 [DOC] Improve docs about keys in GC.stat_heap 2023-08-15 08:54:27 -04:00
Peter Zhu 2498140777 [DOC] Improve docs for GC.start 2023-08-15 08:54:27 -04:00
Peter Zhu 300bc14589 [DOC] Improve some GC docs 2023-08-15 08:54:27 -04:00
Peter Zhu 93ac7405b8 Add marking and sweeping time to GC.stat
There is a `time` key in GC.stat that gives us the total time spent in
GC. However, we don't know what proportion of the time is spent between
marking and sweeping. This makes it difficult to tune the GC as we're
not sure where to focus our efforts on.

This PR adds keys `marking_time` and `sweeping_time` to GC.stat for the
time spent marking and sweeping, in milliseconds.

[Feature #19437]
2023-02-21 08:05:31 -05:00
Peter Zhu 358f325bf8 [DOC] Fix formatting for GC.stat 2023-01-05 09:24:32 -05:00
zverok 5c04ff944e Docs: Fix small glitch in GC 2022-12-23 18:09:49 +02:00