\chapter{Memory management} \label{sec:memory} This chapter describes the memory- and object-management aspects of PCE. \section{Lifetime of an object} \index{garbage collection}\index{object,removing} Object lifetime management is a difficult issue in PCE/Prolog as PCE cannot be aware of all references to PCE objects stored in Prolog. Another complicating factor is that non-incremental garbage collection as performed by most Lisp systems is undesirable because they harm the interactive response of the system. For these reasons PCE performs {\em incremental} garbage collection. It distinguishes a number of prototypical `life-cycles' for objects. Heuristics tell the system which of these is applicable and when the object may be deleted. PCE distinguishes between {\em global-}, {\em top level-}, {\em support-}, {\em argument-} and {\em answer-} objects. {\em Global} objects are created and exist for the entire PCE session: @prolog, class objects, etc. {\em Top-level} objects are the principal objects of the application. They should exist even if no other PCE object refers to them. An example of a top level object is a frame or hash_table representing a database in the application. {\em Support} objects only complete the definition of other objects. If this `other' object is removed, the support object may be removed as well. An example is the area attribute of a graphical. {\em Argument} objects are objects created to serve as an argument to a message. For example a graphical may be moved to a position described by a point object. The point may be deleted when the message is completed. Finally, {\em answer} objects are the result of some computation. For example `area <-size' returns a size object. This object may be deleted when the code that requested the value is done with it. PCE maintains the following information on objects to support garbage collection. This information may be requested using the PCE inspector (see \secref{inspector}). \begin{description} \tick{Protect Flag} This flag may be set using `object ->protect'. When set, the object can not be freed by any means. This flag is set for most global and reusable objects: @prolog, @pce, @display, names, classes, etc. \tick{Lock Flag} This flag indicates that the object may not be removed by the garbage collector. Locked objects can only be freed by sending an explicit `object ->free' message' or using the predicate free/1. It is used to avoid that `top level' objects such as frames are deleted by the garbage collector. It is also used to indicate that Prolog wants to be responsible for destruction of the object rather than PCE's garbage collector. The lock flag is automatically set on any object that has a named reference. If Prolog wants to store integer object references in the Prolog database locking is often necessary to protect the object for the PCE garbage collector. See also \secref{pceprolog}. \tick{Answer Flag} This flag indicates that the object has been created as an answer of some computation or as a result of the Prolog predicate new/2. The {\em answer} status is cleared if the object is used to fill a slot of another object% \footnote{PCE assumes the object has become a {\em support} object. This is generally not correct for code objects. Class \class{code} therefore has `class <-un_answer: @off', which implies that objects that fill a slot of a code object will not loose their `answer' status.} or `object ->done' is invoked on the object. \tick{Reference Count} PCE maintains the number of other objects referring to this object. When the reference count drops to zero and none of the protect, lock or answer flags are set PCE assumes the object is garbage and removes the object from the object base. \end{description} \section{Practical considerations} \index{object,management}% The principal predicates new/2, send/[2-12] and get/[3-13] will destroy all argument- and answer- objects created during their execution except for the object created by new/2 and the object returned by get/[3-13]. An object created by new/2 with an integer (anonymous) object reference must either be attached to another object, locked against PCE's garbage collector or destroyed using `object ->done' if it is created during the {\em initialisation} of the application or in a loop that is passed many times. Such objects will be automatically reclaimed if (1) the object is created while handling a user-event after handling the event is finished or (2) the object is created in the implementation of a method on a user-defined class and the method terminates execution. If is is not known whether or not the result of get/[3-13] is a computed object the user should invoke `object ->done' to this result when the result is no longer needed. This will free the result if it was a computed (and no longer referenced) object and has no effect otherwise. If the result of the get operation is known to be an integer, no such message should be send. \section{Memory usage of objects} \index{object,memory usage}\index{memory usage} Currently an object consists of an object-header and an array of instance variables. The object-header includes various flags, a reference count and a pointer to the class. The size of an object header is 12 bytes. Each instance variable consumes an additional 4 bytes. For example a point object has `x' and `y' instance variables and thus consumes $12 + 2 * 4 = 20$ bytes. The method `class <-instance_size' returns the size of an instance of this class in bytes. Note that the costs of supporting objects is not considered in this value. For example a box object has instance size: \begin{code} 1 ?- get(class(box), instance_size, S). S = 72 \end{code} But a box has an <-area instance variable consuming an additional 28 bytes.