Garbage collection in hush

This document describes the garbage collection mechanisms of hush.

Introduction

It is our firm conviction hat garbage collection should be supported by the language environment, as the developers of Java have realized. In C++ this is unfortunately not the case. Nevertheless, the hush library is becoming increasingly strict in collecting garbage. It may clean up itself one day. Many classes do provide a register method that allows the user to declare which (component) objects must be deleted when cleaning up. In most cases you do not have to be very strict in cleaning up obsolete objects, except when resource management (such as occupying the audio device) is involved. A hush programmer should never, or only very rarely, delete an object explicitly. Rather, one must register each newly created object to a (handler) object that provides the most suitable scope. For example some objects live as long as a session, whereas for other objects the widget they belong to is a more suitable scope. See garbage(4) and handler(4).

Automatic garbage collection for widgets

Widgets that are created as child of an ancestor widget are automatically registered for eventual garbage collection. As a result, deleting a toplevel widget will result in the subsequent deletion of all its children. Note that this strategy mirrors the Tk destroy algorithm.

The root window will be automatically destroyed after quitting the program. This means that all direct and indirect children of the root window are automatically deleted.

Examples

The following widgets are all deleted automatically:

    widget* root = tk->root();       // Get widget of root window
    frame* f1 = new frame(root, "f1");
    button* b1 = new button(f1, "b1");
    ... etc
   

The following widgets are all deleted by deleting top:

    toplevel *top = new toplevel("t1");
    frame* f2 = new frame(top, "f2");
    button* b2 = new button(f2, "b2");
    ... etc
   

Implicit garbage collection for other hush objects

The hush handler class and its descendants have a handler::_register function which can be used to register objects for deletion. Every object registered by a specific handler will be deleted by the destructor of the handler object. Since every widget is derived from handler, you can use the widget's _register member for objects which need to be destructed when the widget itself is destructed. The kit's _register can be used for objects which are needed during a complete hush application.

Examples

Handler will be deleted when kit is deleted:

    handler* h = new myhandler;
    tk->bind("do-something",h);
    tk->_register(h);          
   

Handler will be deleted when button is deleted:

    button* b = new button(parent, "b");
    handler h = new myhandler;
    b->_register(h);
   

Garbage Statistics

After destruction of your session, all hush object should have been deleted. You can check this by calling the static session::statistics member function.

Example

The following main function, for a class app derived from session:
    int main(int argc, char **argv) {
      app *a = new app(argc,argv);  // create a session
      int result = a->run();        // run session
      delete a;                     // delete session
      session::statistics();        // print statistics
      return result;                // return result of run
    }
   
prints something like:
    
    Statistics:   created - deleted = ? 
    session::       2 - 2 = 0
    kit::           2 - 2 = 0
    handler::       24 - 24 = 0
    event::         1 - 1 = 0
    widget::        8 - 8 = 0
    item::          4 - 4 = 0
    binding::       4 - 4 = 0
    string::        0 - 0 = 0
    iter<T>::       0 - 0 = 0
    list<T>::       0 - 0 = 0
    dictionary<T>:: 0 - 0 = 0
    garbage<T>::    0 - 0 = 0
    sublistrep::    0 - 0 = 0
    baselist::      0 - 0 = 0
    cell::          19 - 19 = 0