summaryrefslogtreecommitdiff
path: root/test/ruby/test_gc.rb
AgeCommit message (Collapse)Author
2025-11-19Implement heap_final_slots in GC.stat_heapPeter Zhu
[Feature #20408]
2025-11-19Implement heap_free_slots in GC.stat_heapPeter Zhu
[Feature #20408]
2025-11-19Implement heap_live_slots in GC.stat_heapPeter Zhu
[Feature #20408]
2025-11-04Release VM lock before running finalizers (#15050)Luke Gruber
We shouldn't run any ruby code with the VM lock held.
2025-09-21Exclude failing GC finalizer tests with ASANBenoit Daloze
* See https://bugs.ruby-lang.org/issues/21613
2025-09-03Revert "test_gc.rb: Attempt to stabilize test_interrupt_in_finalizer"Takashi Kokubun
This reverts commit c1c0b32445c66e343c136faa28d7a0f0f46d96a2. This test is clearly not reliable: https://github.com/ruby/ruby/actions/runs/17446920961/job/49543543423 I want to skip this unstable test on GitHub Actions to make sure this test doesn't prevent PRs from getting merged. We can continue to monitor the state of this test on RubyCI and ci.rvm.jp.
2025-09-02test_gc.rb: Attempt to stabilize test_interrupt_in_finalizerTakashi Kokubun
This fails way too often across many environments. I don't think this test is healthy. https://github.com/ruby/ruby/actions/runs/17343611722/job/49240735401 Before we give up on it, let me see if this helps.
2025-08-18Increase timeout on slow tests (#14264)Max Bernstein
2025-08-14Increase timeout for failing testsTakashi Kokubun
https://github.com/ruby/ruby/actions/runs/16969921157/job/48103809963 https://github.com/ruby/ruby/actions/runs/16969655024/job/48102876839
2025-08-11Fix return value of setting in GC.configPeter Zhu
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-06-26Fix flaky TestGc#test_heaps_grow_independentlyPeter Zhu
The test sometimes fails with "Expected 2062788 to be < 2000000" because heap 0 has not been cleared yet by GC. This commit fixes it to run GC before the assertion to ensure that it does not flake.
2025-06-15Relax the criteria of flaky weak_references count testNobuyoshi Nakada
2025-06-15Simplify weak_references count test initializationNobuyoshi Nakada
Using an enumerator does not resolve the intermittent failures: 100+ failures in 10,000 iterations.
2025-06-08increase timeout for high load envKoichi Sasada
I can reproduce timeout failure with the high load machine: ``` $ RUBY_MAX_CPU=100 ruby -e '100.times{Ractor.new{loop{}}}; sleep' & $ while make test-all -o exts -o encs TESTS='ruby/gc -n /test_interrupt_in_finalizer/ --repeat-count=100'; do date; done .... Finished(93/100) tests in 0.653434s, 1.5304 tests/s, 7.6519 assertions/s. Finished(94/100) tests in 0.614422s, 1.6275 tests/s, 8.1377 assertions/s. [1/1] TestGc#test_interrupt_in_finalizer = 11.08 s 1) Timeout: TestGc#test_interrupt_in_finalizer ```
2025-06-05Add debug message to test_heaps_grow_independentlyPeter Zhu
To debug flaky failures on i686 that look like: 1) Failure: TestGc#test_heaps_grow_independently [test/ruby/test_gc.rb:704]: Expected 2061929 to be < 2000000. Notes: Merged: https://github.com/ruby/ruby/pull/13140
2025-06-05mark main Ractor objectKoichi Sasada
`RUBY_DEBUG=gc_stress ./miniruby -e0` crashes because of this marking miss. BTW, to use `RUBY_DEBUG=gc_stress` we need to specify `--enable-debug-env` configure option. This is why I couldn't repro on my environments. see c0c94ab183d0d428595ccb74ae71ee945f1afd45 Notes: Merged: https://github.com/ruby/ruby/pull/13506
2025-05-31skip failing test in a weekKoichi Sasada
``` 1) Failure: TestGc#test_gc_stress_at_startup [/home/chkbuild/chkbuild/tmp/build/20250530T213003Z/ruby/test/ruby/test_gc.rb:799]: [Bug #15784] pid 1748790 killed by SIGSEGV (signal 11) (core dumped). 1. [3/3] Assertion for "success?" | Expected #<Process::Status: pid 1748790 SIGSEGV (signal 11) (core dumped)> to be success?. ```
2025-04-28Fix nondeterministic failure in test_latest_gc_info_weak_references_countJeremy Evans
Clear the ary variable before setting it to nil. Otherwise, if the previous ary value was somewhere on the stack, all references in it would be considered live, and the wmap size would be 10000.
2025-04-07Grow GC heaps independentlyPeter Zhu
[Bug #21214] If we allocate objects where one heap holds transient objects and another holds long lived objects, then the heap with transient objects will grow along the heap with long lived objects, causing higher memory usage. For example, we can see this issue in this script: def allocate_small_object = [] def allocate_large_object = Array.new(10) arys = Array.new(1_000_000) do # Allocate 10 small transient objects 10.times { allocate_small_object } # Allocate 1 large object that is persistent allocate_large_object end pp GC.stat pp GC.stat_heap Before this change: heap_live_slots: 2837243 {0 => {slot_size: 40, heap_eden_pages: 1123, heap_eden_slots: 1838807}, 2 => {slot_size: 160, heap_eden_pages: 2449, heap_eden_slots: 1001149}, } After this change: heap_live_slots: 1094474 {0 => {slot_size: 40, heap_eden_pages: 58, heap_eden_slots: 94973}, 2 => {slot_size: 160, heap_eden_pages: 2449, heap_eden_slots: 1001149}, } Notes: Merged: https://github.com/ruby/ruby/pull/13061
2025-04-01[Bug #21203] Skip TestGc#test_gc_parameter_init_slots since it is flaky (#13025)Naoto Ono
https://bugs.ruby-lang.org/issues/21203 TestGc#test_gc_parameter_init_slots is a flaky test that fails intermittently. Until the issue with flakiness is resolved, I will skip it. Notes: Merged-By: ono-max <onoto1998@gmail.com>
2025-03-11Fix flaky test_latest_gc_info_need_major_byPeter Zhu
The test could flake because a major GC could be triggered due to allocation for caches or other things, which would cause the test to fail.
2025-03-10Bump tolerance for weak reference test from 1 to 2Peter Zhu
The test fails sometimes with: TestGc#test_latest_gc_info_weak_references_count [test/ruby/test_gc.rb:421]: Expected 2 to be <= 1. Notes: Merged: https://github.com/ruby/ruby/pull/12894
2025-02-13[Feature #21116] Extract RJIT as a third-party gemNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12740
2024-11-14rb_raise when attempting to set the GC implementation nameMatt Valentine-House
Instead of silently ignoring the key, we should raise to clearly tell the user that this key is read-only. Notes: Merged: https://github.com/ruby/ruby/pull/11872
2024-11-14Expose GC.config[:implementation], to query the currently active GCMatt Valentine-House
And a default and readonly key to the GC.config hash that names the current GC implementation. This is provided by each implementation by the API function rb_gc_impl_active_gc_name Notes: Merged: https://github.com/ruby/ruby/pull/11872
2024-11-06Fix flakiness in TestGc#test_thrashing_for_young_objectsKJ Tsanaktsidis
I caught a reproduction of this test failing under rr, and was able to replay it to isolate the failure. The call to `before_stat_heap = GC.stat_heap` is itself allocating a hash, which in unlucky circumstances can result in a new page being allocated and thus `before_stats[:heap_allocated_pages]` no longer equals `after_stats[:heap_allocated_pages]`. The solution is to use the form of GC.stat/stat_heap which takes a hash as an argument, and thus needs to perform no Ruby allocations itself. Notes: Merged: https://github.com/ruby/ruby/pull/11997
2024-10-11Remove defined check for GC.config in test_gc.rbPeter Zhu
GC.config is always defined. Notes: Merged: https://github.com/ruby/ruby/pull/11867
2024-10-10Fix typo in test_gc.rb [ci skip]Peter Zhu
2024-10-03Rename size_pool -> heapMatt Valentine-House
Now that we've inlined the eden_heap into the size_pool, we should rename the size_pool to heap. So that Ruby contains multiple heaps, with different sized objects. The term heap as a collection of memory pages is more in memory management nomenclature, whereas size_pool was a name chosen out of necessity during the development of the Variable Width Allocation features of Ruby. The concept of size pools was introduced in order to facilitate different sized objects (other than the default 40 bytes). They wrapped the eden heap and the tomb heap, and some related state, and provided a reasonably simple way of duplicating all related concerns, to provide multiple pools that all shared the same structure but held different objects. Since then various changes have happend in Ruby's memory layout: * The concept of tomb heaps has been replaced by a global free pages list, with each page having it's slot size reconfigured at the point when it is resurrected * the eden heap has been inlined into the size pool itself, so that now the size pool directly controls the free_pages list, the sweeping page, the compaction cursor and the other state that was previously being managed by the eden heap. Now that there is no need for a heap wrapper, we should refer to the collection of pages containing Ruby objects as a heap again rather than a size pool Notes: Merged: https://github.com/ruby/ruby/pull/11771
2024-09-17Replace all GC.disable with EnvUtil.without_gcPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/11635
2024-09-09Add keys to GC.stat and fix testsPeter Zhu
This adds keys heap_empty_pages and heap_allocatable_slots to GC.stat.
2024-09-09Switch sorted list of pages in the GC to a darrayPeter Zhu
2024-09-02Fix flaky test_latest_gc_info_need_major_byPeter Zhu
It's possible for a GC to run between the calls of GC.latest_gc_info, which would cause the test to fail. We can disable GC so that GC only triggers manually.
2024-08-19Make assertions allow incremental GC when disabledPeter Zhu
When assertions are enabled, the following code triggers an assertion error: GC.disable GC.start(immediate_mark: false, immediate_sweep: false) 10_000_000.times { Object.new } This is because the GC.start ignores that the GC is disabled and will start incremental marking and lazy sweeping. But the assertions in gc_marks_continue and gc_sweep_continue assert that GC is not disabled. This commit changes it for the assertion to pass if the GC was triggered from a method. Notes: Merged: https://github.com/ruby/ruby/pull/11391
2024-08-11Fix flag test macroNobuyoshi Nakada
`RBOOL` is a macro to convert C boolean to Ruby boolean. Notes: Merged: https://github.com/ruby/ruby/pull/11351
2024-07-12Rename full_mark -> rgengc_allow_full_markMatt Valentine-House
2024-07-12Provide GC.config to disable major GC collectionsMatt Valentine-House
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-05Fix flaky test_stat_heap_allPeter Zhu
We only collect GC.stat_heap(nil, stat_heap_all) once, outside of the loop, but assert_equal could allocate objects which can cause a GC to run and cause stat_heap_all to be out-of-sync.
2024-07-03[Feature #20470] Split GC into gc_impl.cPeter Zhu
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-06-07TestGc#test_thrashing_for_young_objects: extend the timeout limitYusuke Endoh
2024-03-27Revert "skip `test_gc_stress_at_startup`"Peter Zhu
This reverts commit 3680981c7b71df8c3a426164787ccefe5296bb25.
2024-03-26skip `test_gc_stress_at_startup`Koichi Sasada
(maybe) from 9cf754b the test fails on some environments: https://rubyci.s3.amazonaws.com/icc-x64/ruby-master/log/20240325T200004Z.fail.html.gz ``` 1) Failure: TestGc#test_gc_stress_at_startup [/home/chkbuild/chkbuild/tmp/build/20240325T200004Z/ruby/test/ruby/test_gc.rb:771]: [Bug #15784] pid 1087168 killed by SIGSEGV (signal 11) (core dumped). 1. [3/3] Assertion for "success?" | Expected #<Process::Status: pid 1087168 SIGSEGV (signal 11) (core dumped)> to be success?. ``` https://rubyci.s3.amazonaws.com/freebsd14/ruby-master/log/20240325T203002Z.fail.html.gz https://rubyci.s3.amazonaws.com/osx1200arm-no-yjit/ruby-master/log/20240325T195003Z.fail.html.gz https://rubyci.s3.amazonaws.com/s390x/ruby-master/log/20240325T210003Z.fail.html.gz ... so just skipt it until it works.
2024-01-06Add test case for GC.measure_total_timeRian McGuire
2023-12-19restore the stack pointer on finalizerKoichi Sasada
When error on finalizer, the exception will be ignored. To restart the code, we need to restore the stack pointer. fix [Bug #20042]
2023-12-18Fix flaky test test_stat_heapPeter Zhu
The test sometimes fails with: 1) Failure: TestGc#test_stat_heap [/tmp/ruby/src/trunk-repeat50/test/ruby/test_gc.rb:169]: Expected 33434403 to be <= 33434354.
2023-12-12Skip a GC test for RJITTakashi Kokubun
It randomly fails like this: https://github.com/ruby/ruby/actions/runs/7191443542/job/19586164973
2023-12-07Fix SEGV caused by `GC::Profiler.raw_data` (#9122)Soutaro Matsumoto
2023-10-18Loosen assertion for flaky weak references testPeter Zhu
2023-09-08Fix weak_references count testMatt Valentine-House
This test creates a lot of Objects held in an array, and a set of weak references to them using WeakMap. It then clears the array and frees it and asserts that all the weak references to it are also gone. This test is failing because one of the dummy objects in our weakmap is ending up on the stack, and so is being marked, even though we thought that we'd removed the only reference to it. This behaviour has changed since this commit: https://github.com/ruby/ruby/commit/5b5ae3d9e064e17e2a7d8d21d739fcc62ae1075c which rewrites `Integer#times` from C into Ruby. This change is somehow causing the last object we append to our array to consistently end up on the stack during GC. This commit fixes the specific weakmap test by using an enumerator and each, instead of `Integer#times`, and thus avoids having our last object created end up on the stack. Notes: Merged: https://github.com/ruby/ruby/pull/8402
2023-08-31Correctly calculate initial pagesPeter Zhu
The old algorithm could calculate an undercount for the initial pages due to two issues: 1. It did not take into account that some heap pages will have one less slot due to alignment. It assumed that every heap page would be able to be fully filled with slots. Pages that are unaligned with the slot size will lose one slot. The new algorithm assumes that every page will be unaligned. 2. It performed integer division, which truncates down. This means that the number of pages might not actually satisfy the number of slots. This can cause the heap to grow in `gc_sweep_finish_size_pool` after allocating all of the allocatable pages because the total number of slots would be less than the initial configured number of slots. Notes: Merged: https://github.com/ruby/ruby/pull/8333