From Wikibooks, open books for an open world
Ruby does automatic Garbage Collection.
MRI's GC is a "full mark and sweep" and is run whenever it runs out of memory slots (i.e. before adding more memory, it will sweep the existing to see if it can free up some first--if not it adds more memory). It also is triggered after GC_MALLOC_LIMIT of bytes has been allocated by extensions. Unfortunately this causes a traversal of all memory, which is typically slow. See a good description.
The GC is known to typically take 10% of cpu, but if you have a large RAM load, it could take much more.
GC can be tuned at "compile time" (MRI/KRI's < 1.9) http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning or can be tuned by using environment variables (REE, MRI/KRI's >= 1.9).
Some tips:
You can set the compiler variable GC_MALLOC_LIMIT to be a very high value, which causes your program to use more RAM but to traverse it much less frequently. Good for large apps, like rails.
You can use jruby/rubinius which use more sophisticated GC's.
You can use "native" libraries which store the values away so that Ruby doesn't have to keep track of them and collect them. Examples: "NArray" gem and "google_hash" gem.
To turn it off: @GC.disable@
To force it to run once: @GC.start@
Ruby's (MRI's) GC is mark and sweep, which means it is conservative. To accomplish this, it traverses the stack, looking for any section of memory which "looks" like a reference to an existing ruby object, and marks them as live. This can lead to false positives, even when there are no references to an object remaining.
This problem is especially bad in the 1.8.x series, when they don't have the MBARI patches applied (most don't, REE does). This is because, when you use threads, it actually allocates a full copy of the stack to each thread, and as the threads are run, their stack is copied to the "real" stack, and they can pick up ghost references that belong to other threads, and also because the 1.8 MRI interpreter contains huge switch statements, which leave a lot of memory on the stack untouched, so it can continue to contain references to "ghost" references in error.
This all means that if you call a GC.start, it's not *guaranteed* to collect anything.
Some hints around this:
a = SomeClass.new begin ... ensure a.cleanup end
"here":http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/27550 is an example of how to tune Jruby's GC. The G1GC is theoretically a "never pause" GC, though in reality most of them are pretty good at being speedy. For long running apps you'll probably want to run in server mode (--server), for increased performance, though decreased startup time.
Rubinius is also said to have a better GC.
Since MRI's GC is basically O(N) as it grows, you get a performance penalty when GC's occur and you are using a lot of RAM in your app (and MRI almost never gives its RAM back to the system). Workarounds:
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4