Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An object with defined singleton method and no external references is not GC from memory #4985

Closed
brometeo opened this issue Jan 17, 2018 · 2 comments

Comments

@brometeo
Copy link

brometeo commented Jan 17, 2018

Environment

  • JRuby version: 9.1.15.0
  • Java version: OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-1-b12). 64 -Bit server VM
  • flags: --enable=frozen-string-literal -J-Djruby.reify.classes=true -J-XX:+UseCompressedOops -J-XX:+UseCMSInitiatingOccupancyOnly -J-XX:CMSInitiatingOccupancyFraction=50 -X-C -J-Xmx300m -J-XX:+CMSClassUnloadingEnabled -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1
  • Operating system and platform: Linux bree 4.14.0-2-amd64 break script engine #1 SMP Debian 4.14.7-1 (2017-12-22) x86_64 GNU/Linux

Here you have potentially offending code:

require 'pry'
  
class Foo
  def define_bar_method(&block)
    define_singleton_method(:bar, &block)
  end

  def remove_bar_method
    singleton_class.class_eval do
      remove_method :bar
    end
  end
end

foo = Foo.new
foo.define_bar_method {2 + 2}
foo.bar
foo.remove_bar_method
foo = nil
binding.pry

Expected Behavior

An object with a defined singleton method should be garbage collected if there are no external references pointing it.

Actual Behavior

When referenced by a Binding object from a defined singleton method, foo object is not collected by GC and it seems it should be. I try to remove singleton method before GC.

On pry stop, I try GC from visualvm. Foo object is still there if I run a memory sampling from visualvm. More GC don't change that situation.

@headius
Copy link
Member

headius commented Feb 13, 2018

Same issue as #4968 most likely.

@headius
Copy link
Member

headius commented Feb 13, 2018

Workaround is to use those objects/variables in a subscope. For example:

tap {
  foo = Foo.new
  foo.define_bar_method {2 + 2}
  foo.bar
  foo.remove_bar_method
}
binding.pry

Not ideal I know.

@headius headius closed this as completed Feb 13, 2018
@headius headius added this to the Invalid or Duplicate milestone Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants