Frag Logo
  Frag Home | Frag SF Project   index | contents | previous | next

Garbage Collector

Object References

Frag uses a garbage collection scheme based on explicit reference to objects. Once an object has no references anymore, the object gets automatically garbage collected.

Every use of an object or every reference from a data structure (such as a variable, a list, or the interpreter's result) counts as a reference to an object. Hence, when you want to preserve an object, be sure to keep at least one reference to it.

As a user of Frag you only seldom have to care for garbage collection at all. Usually it is transparently done "in the background". There are some exceptional cases, where you should care. These are explained below. But before that, let us look at how garbage collection relates to named and unnamed object, as well as object creation in general.

Object Names and Unnamed Objects

create (see Section create) creates a new instance of a class. If no object name is given to create an unnamed object is created. For details about object creation see Section Object and Class Concept. unname (see Section unname) tells the interpreter to forget the name of an object. An object name is like a reference to the object. If the object has no reference, it gets garbage collected. Hence, unname can be used to dispose named objects, once they are no longer needed.

Unnamed objects have an automatically assigned ID, of the form: %%number, such as %%12. Once unname is called on an object, its name is forgotten, and it gets an automatically assigned ID, which is returned by unname.

An unnamed object is immediately garbage collected, once there are no more references to it. For instance, the object created in the following invocation is directly removed from the interpreter by the garbage collector:
Object create

Hence, we should directly assign an unnamed object to a variable to preserve it. However, when the variable is disposed (e.g., here when the local scope is closed), the unnamed object stored in the variable gets garbage collected.
set o [Object create]
The unnamed object can now be accessed via the variable, e.g.: $o set x 1.

It is advisable to use named objects for instances that should survive, even if no one references them. Typical examples are objects that are used as classes: They are typically realized as named objects. Unnamed objects are used for short-living instances, or for instances that occur in great numbers or consume a lot of memory, and hence they should get garbage collected, once they are not in use anymore.

Duals

In some seldom cases, for a user of Frag it is important to understand some details of how garbage collection works internally. In particular, Frag internally uses a structure, called Duals, for representing all words in the language. Each Dual has two representations: the string representation shown to the user of the language and an internal implementation. For instance, a Frag Object has its object name as its string representation and the FragObject Java class instance as its DualValue representation.

A reference to a Frag Object only counts for garbage collection, if you use a Dual with a DualValue of type FragObject. However, there are also other Dual types, such as ListValue or StringValue.

Consider the following example:
Object create A
# ... something else happens
# ...
set r A
A unname     
A central strength of Frag is that it can treat strings as object names and vice versa, because this enables all sorts of easily treating code as data, and data as code - using a simple and uniform syntax. Frag usually "guesses" whether you want to preserve an object via a reference or not. In the example case above, the StringValue in the variable r is just an ordinary string, and does not refer to the object A. You can use the string in r to access the object, but it is not counted as a reference. Hence, the unname invocation causes the object A to be garbage collected.

If you want to preserve A, even though it is unnamed later on, you must keep a reference to the FragObject dual value, which is for instance returned by create:
set r [Object create A]
A unname     
This code would unname A but not garbage collect it. It could still be accessed via $r.

You can refactor the code above like this to be sure to store an object reference in "r":
Object create A
# ... something else happens
# ...
set r [A getObjectID]
A unname

Object references are returned by all methods of Frag that create or introspect objects. Examples are: create, unname, self, callstack self, callstack class, and many predefined getter-methods that return object lists, like interp getObjects or Object's getClasses. Some of these methods return lists of objects. If you store such a list in a variable, the references are preserved as well.

For instance, the following code:
set stringList {Student Lecturer}
Object create Student
Object create Lecturer
Object create joe -classes Student Lecturer
# preserve the references
set cls [joe getClasses]
# unname one of the classes
Lecturer unname
puts "String List: $stringList, Class List: $cls"
prints something like:
String List: Student Lecturer, Class List: Student %%1
You can see that the string list is unaffected by object unnaming - as it should be, because you don't want your ordinary lists and strings to change just because you unname an object. But in the class list, we now refer to the unnamed object %%1, as this is the only left reference maintained for the former Lecturer object. Only if the reference in cls is discarded, the object gets garbage collected.

You can also explicitly transform a string into an object reference, using getObjectID, which simply returns a Dual with the object's FragObject reference in it. For instance, you could transform the given string list into an object list:
set stringList {Student Lecturer}
Object create Student
Object create Lecturer
Object create joe -classes Student Lecturer
set newList ""
foreach str $stringList {
    # the references are now preserved in "newList"
    append newList [$str getObjectID]
}
Lecturer unname
puts "New List: $newList"
As newList contains references, the result again looks like:
New List: Student %%1
On the other hand, you can use the string methods to transform an object reference into a string, and hence cause it to be not reference counted. In both cases in the example below, the objects are not preserved, because only a string points to their names, but no object references are preserved.
set r1 [string build [Object create]]
set r2 [string append "" [Object create]]
set e1 [catch {$r1 set x 1}]
set e2 [catch {$r2 set x 1}]

Extending Frag from Java

If you extend Frag from Java, and maintain references to Frag objects in Java, you must increase their reference count. When you release a reference to an object, you must decrease its reference count.

When you implement or use structures like variables or lists that might contain Frag objects, be sure to handle reference counting - just like the examples in the Frag implementation. An important example are wrappers to Java containers: if you can put Frag objects into such a wrapper from within Frag, be sure that they are preserved and released using the reference counting functions.

At the moment there is no tutorial on how to extend Frag from Java. But in the Frag implementation there are many examples, such as the classes File, Hashtable, HashtableWrapper, etc.

  index | contents | previous | next