Why isn't this simple class garbage collected in Ruby console?
It seems this was already answered in another question
Pry stores the output of the last 100 commands and thus the object can't actually be garbage collected.
Anonymous modules and classes garbage collection in Ruby
ObjectSpace.garbage_collect does not mean that a garbage collection will be performed. It's only a hint to the Ruby runtime.
On some platforms it isn't even possible for the Ruby runtime to initiate a garbage collection, because the garbage collector isn't even part of the Ruby runtime, e.g on JRuby or IronRuby.
In general, the Ruby runtime will decide on its own when it will perform a garbage collection. Usually, that's when it runs out of memory. 100000 modules aren't that big, so there's simply no need to perform a GC cycle.
Also, most Ruby implementations will never release memory back to the OS, even after a GC cycle.
So, just the fact that the
ObjectSpace doesn't shrink doesn't necessarily mean that you have memory leak. It could simply mean that the Ruby runtime didn't yet deem it necessary to run a GC cycle.
Also note that if you run this code from IRb, Pry, an IDE console or some other non-standard environment, then it may be the case that those hold on to some of those modules. For example, Pry stores the results of the last 100 commands in a history array. (Try evaluating
_out_ in Pry, after entering your example program.)
How to destroy Ruby object?
Other than hacking the underlying C code, no. Garbage collection is managed by the runtime so you don't have to worry about it. Here is a decent reference on the algorithm in Ruby 2.0.
Once you have no more references to the object in memory, the garbage collector will go to work. You should be fine.
Sizes of object for garbage collector
The guy who said that you should benchmark it is right -- GC is a complex issue and it's hard to give a 100% correct answer.
Also, it depends on the implementation being used. In JRuby, it's the JVM doing the work. In MRI, it's a mark-and-sweep GC.
On the case of MRI, it works more or less like this: each time that the Ruby interpreter needs more memory, it runs the GC to try and free it. If there isn't enough memory, it'll allocate more. And the GC decides that an object is ok to be freed ("mark" it) when there aren't references to it.
The only advice I can give you is to avoid using lots of objects that can't be garbage collected. For example, if you're building an array of strings (their size isn't important), you should see performance degradation much more rapidly than if you created a big string concatenating each of the smaller ones.
This is because in the latter the GC can destroy the small strings after they're used, while in the former the array is always maintaining a reference to each one of them.
EDIT: Of course, this assumes that the cost of maintaining them in memory is bigger than the slowdown of dealing with the "big string". In some cases, it's better to have small strings and then concatenate they all -- resulting in a single slow operation. Again, these are just examples without benchmarks, don't take them very seriously.
Include Erb Delimiters Inside of a String in an Erb Block
Requiring a Ruby Gem in Ruby Script Breaks Cron Job Execution
Is There an Elegant Way to Exclude the First Value of a Range
What Could Be Causing This Rails Ioerror Closed Stream
Sinatra Helper to Fake a Request
Why Won't Ruby Allow Me to Specify Self as a Receiver Inside a Private Method
Rails Activeadmin Drop Down Menu on New and Edit Forms
Cocoapods Folder Does Not Exist/Permissions Error
Prawn PDF: I Need to Generate Nested Tables
Exec Onlyif Registry Value Is Not Present
Installing Ncurses for Ruby on Windows
Generic Way to Replace an Object in It's Own Method
Closures and for Loops in Ruby
Ruby Error Reading in Certificate File with Openssl
What's Wrong with the Square and Rectangle Inheritance
Ruby How to Merge Two CSV Files with Slightly Different Headers