Issue #22251 has been updated by Eregon (Benoit Daloze). Status changed from Open to Closed Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.3: WONTFIX, 3.4: REQUIRED, 4.0: REQUIRED My reproducer isn't prefect because the `1; []; 0` output would be correct if a GC happens at the start of `m.keys`, but we can disable the GC to resolve that concern and make it fully reliable. nobu (Nobuyoshi Nakada) wrote in #note-1:
`master` b52af71445 works as expected.
Indeed, I should have checked, I'll close this and mark for backport then, both 3.4 and 4.0 seem affected, in fact since `ruby-3.3.0-preview2`: ``` $ ruby -ve 'GC.disable; m = ObjectSpace::WeakMap.new; Thread.new { m[Object.new] = Object.new }.join; GC.start; p m.size; p m.keys; p m.size' ruby 4.1.0dev (2026-08-08T08:04:35Z master e56f452e46) +PRISM [x86_64-linux] 0 [] 0 $ docker run -it -e ALL_RUBY_SINCE=3.0.0 ghcr.io/ruby/all-ruby /all-ruby/all-ruby -e 'GC.disable; m = ObjectSpace::WeakMap.new; Thread.new { m[Object.new] = Object.new }.join; GC.start; p m.size; p m.keys; p m.size' ruby-3.0.0 0 [] 0 ... ruby-3.3.0-preview1 0 [] 0 ruby-3.3.0-preview2 1 [] 0 ... ruby-4.0.6 1 [] 0 ``` ---------------------------------------- Bug #22251: ObjectSpace::WeakMap#size can return a stale value https://bugs.ruby-lang.org/issues/22251#change-118600 * Author: Eregon (Benoit Daloze) * Status: Closed * ruby -v: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +PRISM [arm64-darwin25] * Backport: 3.3: WONTFIX, 3.4: REQUIRED, 4.0: REQUIRED ---------------------------------------- ``` $ ruby -e 'm = ObjectSpace::WeakMap.new; Thread.new { m[Object.new] = Object.new }.join; GC.start; p m.size; p m.keys; p m.size' 1 [] 0 ``` The first line is 1 but I would expect 0. Interestingly calling `#keys` seems to force an update. If I GC twice then it seems correct: ``` $ ruby -e 'm = ObjectSpace::WeakMap.new; Thread.new { m[Object.new] = Object.new }.join; GC.start; GC.start; p m.size; p m.keys; p m.size' 0 [] 0 ``` Could we decrease size whenever we "remove" an entry? Apologies if that's already known, I searched for an existing issue for this but didn't find anything. -- https://bugs.ruby-lang.org/