4.2.14 Drain Variables

When exiting a procedure, memory and any other resources aquired by the procedure need to be released. The Drain command in conjunction with Drain methods are used to release memory and other resources. Any Local variables are automatically Drained when leaving a procedure. You only need to use the Drain command when writing low level procedures that manage memory along with the Clean command.

When a program terminates Global variables are drained in a process called Liberation. Similarly Globals are initialized when a program starts; which is called Elaboration.

Operands to a Drain command are a list of variables whose resources are to be released. Usually operands are structures. For operands with a primitive type, only Strings use dynamically allocated memory that needs to be freed. Numeric variables and enumerations do not use dynamic memory so there is nothing to release.

Structures are drained either by invoking a Drain method as described below or automatically. Each field within a structure is individually drained. Memory used by String fields is always automatically deallocated. Fields with a numeric or an enumerated type do not need to be drained. Fields that are themselves structures are drained recursively.

If a field that is a Wizard pointer references an object it will not be automatically drained. This is when a Drain method needs to be written. When leaving a procedure, if a Drain method exists for a structure then it will automatiacally but called. Not all referenced data needs to be released, but Dynamic structures referenced by a pointer field need to be explicitly released.

Operands on a Drain (or Clean) command may be a scalar variable, array, or a Wizard pointer. A reference pointer cannot be used as an argument. The Clean operation initializes variables and is automatically applied to all Local variables when entering a method.


Drain Method

Any Class that declares a structure can also declare a Drain method to explicitly release memory and other resources used within the Class. When a variable with a structure type is drained and there is a Drain method coded for the structure it is automatically invoked.

Explicit calls to Drain methods generally do not need to be coded. Instead they are automatically called for Local variables when returning from a procedure or unwinding the call stack after an exception is raised.

If a Drain method is to be invoked from a pure procedure it also needs to be pure. Since releasing resources could have side effects, not all Drain methods can be pure. For example to drain a file handle you'll need to close the file; which is an I/O operation with side effects.

Should a Drain method raise an exception then it is treated as a program fault. When this happen the program will be in a corrupt state and can try to recover or terminate.


Memory Management

To explicitly manage memory it helps to know the life cycle of a variable.


A Class containing a type declaration with pointers to dynamically allocated memory is typically coded with at least one initialized field serving as a "first time thru" flag. A single field can be initialized if you want to minimize overhead when cleaning a variable.


Importing the generic Empty.Type class adds the Empty method. To add that plus New and Free methods import the Dynamic.Type class instead. The New and Free methods dynamically allocate and deallocate memory. The Empty method drains then cleans a variable or array.


Clean Variables

Method Procedure