Project

General

Profile

Actions

Bug #19041

closed

Weakref is still alive after major garbage collection

Added by parker (Parker Finch) over 1 year ago. Updated about 1 year ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin21]
[ruby-core:110218]

Description

I am able to get into an infinite loop waiting for garbage collection to take a WeakRef.

Reproduction Process

The following script prints a "0", then a "1", and then hangs forever. I expect it to keep printing numbers.

require "weakref"

iterations = 0

loop do
  print "\r#{iterations}"
  obj = WeakRef.new(Object.new)
  GC.start while obj.weakref_alive?
  iterations += 1
end

Ruby Version

I have tested this on Ruby 3.1.2, 3.1.0, 3.0.4, 3.0.0, 2.7.6, and 2.7.0 on macOS. All exhibit this behavior.

Further Investigation

Sleeping

Sleeping before the garbage collection allows the loop to continue. The below exhibits the expected behavior:

require "weakref"

iterations = 0

loop do
  print "\r#{iterations}"
  obj = WeakRef.new(Object.new)
  (sleep(0.5); GC.start) while obj.weakref_alive?
  iterations += 1
end

However, sleeping after the garbage collection still shows the buggy behavior (loop hangs):

require "weakref"

iterations = 0

loop do
  print "\r#{iterations}"
  obj = WeakRef.new(Object.new)
  (GC.start; sleep(0.5)) while obj.weakref_alive?
  iterations += 1
end

Running Garbage Collection Multiple Times

Explicitly running garbage collection multiple times allows the loop to continue. This has the expected behavior, more numbers continue to be printed:

require "weakref"

iterations = 0

loop do
  print "\r#{iterations}"
  obj = WeakRef.new(Object.new)
  while obj.weakref_alive?
    GC.start
    GC.start
    GC.start
  end
  iterations += 1
end

However, with certain rubies, running those garbage collection calls in a times block prevents even a single iteration from completing. The following prints only "0" with ruby 3.0.4 on macOS, ruby 2.7.6 on macOS, and ruby 3.1.2 on linux (ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux] on a virtual machine). It shows the expected behavior on ruby 3.1.2 on macOS.

require "weakref"

iterations = 0

loop do
  print "\r#{iterations}"
  obj = WeakRef.new(Object.new)
  3.times { GC.start } while obj.weakref_alive?
  iterations += 1
end

Files

manifest_weakref_issue.rb (1.52 KB) manifest_weakref_issue.rb Script to reproduce the issue parker (Parker Finch), 02/03/2023 02:49 PM

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #19460: Class not able to be garbage collectedClosedActions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0