What happens to ruby objects after the script has run? Are they tidied away out of memory by the Ruby system or SketchUp or do they hang around using up memory until you quit SketchUp?
It depends upon what type of objects are created by the Ruby code.
Entities (models or objects belonging to a model) are handled by SketchUp and stick even when there is no reference in Ruby. Pure Ruby objects are garbage collected and removed when no longer referenced.
The general rule is that you don’t need to worry about it. Ruby is a high level language designed for the user to focus on their goals in a more “idealistic” sense. The Ruby interpreter handles these technical minutia for you.
Have you encountered a specific case where you suspect there is a memory leak or is it more of a general question?
They are pure Ruby data objects such as integers, floating point numbers, strings and arrays and hashes containing the later. They are not SketchUp entities.
That sounds perfect. It is what I thought.
No, I have not encountered a memory leak. It is just a general question.
I’m reassured that the Ruby language tidies up ‘the mess’ after my code runs.
Ruby garbage collection works in particular ways, depending upon how the objects are referenced and what scope they are used in.
The general rule for a shared objectspace like SketchUp’s Ruby environment, is that ALL of your code should evaluate within your unique top level namespace module. Each of your extensions most likely need to also be separate from one another, each in their own unique submodule of your unique namespace module.
So … within your modules or classes, when you define methods, and they have local variables (references) within them, these references will “go out of scope” when the method call ends. Therefore, the objects that they reference will become “unreferenced” and subject to Ruby’s automatic garbage collection.
@vars defined within your modules or classes are not automatically garbage collected. You can “mark” instance
@vars for garbage collection by setting them to reference
@vars that hold references to objects within instances of your classes will go “out of scope” when that instance is destroyed (usually by garbage collection because that instance is no longer referenced.)
@@vars defined within your modules or classes are also not automatically garbage collected.
In order to cleanup class/module
@@var references, you must use the
The same is true of constants within your modules and classes. They are not automatically garbage collected. You must use the
However, this method has been changed so that constants that reference module objects are not undefined. If for example, you were done with one of your extension submodules, then I would think you would first need to be sure it did not have any lingering need (ie, a UI command pointing at one of it’s method objects, etc.), and then reassign that module reference to
nil before undefining the submodule’s constant.
Although we encourage (and in most cases enforce) the wrapping of code within a unique top level module, they are cases where coders just run a sequential set of unwrapped Ruby statements at the top level (within class
Object) by using the Ruby global
#load method. However, the 2nd
wrap argument should be set
true so as to protect SketchUp’s top level
ObjectSpace from having any variable references being defined globally.
#require method is similar in that it cleans up unwrapped local variable references, but not constants (which can be module and class definitions) and other references.
I strongly suggest reading the docs and fully understanding these two global methods.
ADD: A note about integers. They are an ordinal set of “immediate” objects. They themselves are never GC’d. But your references (of whatever kind) to any particular integer in the set can be cleaned up by it going out of scope, or assigning the reference to something else (such as
Thank you for the comprehensive lesson. I will refer to what you have written and try hard to eliminate anything in my code which might leave something ‘hanging around’.
Sounds like there isn’t but I will try to test for it.
There are books in the Ruby Resource book list that have chapters on garbage collection and persistence of objects.
Note that it’s possible to create circular references that prevents the data from being garbage collected. In particular I’ve run into that with callbacks, like one use for Web/HtmlDialogs. Ruby will allow the block to reference the parent scope variables which can in turn lead to circular references.
I’ve had extensions where I created some large objects (often with HtmlDialogs when passing JSON data around) that would accumulate.
There are ways to detect this and address it, but I’d have to look up my own notes before I can produce a good example of this.
A typical Ruby application (website running on a server) the Ruby “app” is often short lived. When Ruby is embedded in a long running desktop application these circular references can in face become a memory hog.
Or, it may be a stable app and run for hours/days. I work quite a bit with a popular Ruby web/app
Re GC/memory, etc - one thing that may hinder GC is bindings associated with blocks, etc. If one has collections (arrays, hashes, etc), clearing them may help GC and happen quickly enough that it doesn’t affect the UI.