Memory Management
In a work-session, geometry modeling applications create and delete a certain number of C++ objects. In this context, memory allocation and de-allocation standard functions are not suited to the system's requirements and for this reason a specialized Memory Manager is implemented into Open CASCADE Technology. The Memory Manager is based on the following principles:
small memory arrays are grouped into clusters and then recycled (clusters are never released to the system),
large arrays are allocated and de-allocated through the standard functions of the system (the arrays are released to system when they are no longer used).
To lighten usual programming difficulties linked to the management of object life duration – before deleting an object, the user must ensure the object is no longer referenced – the delete function is secured by a reference counter. A smart-pointer called a Handle automates reference counter management and automatically deletes an object when it is no longer referenced – the application never calls the delete operator explicitly. To benefit from the memory manager in OCCT, transient classes must inherit from TShared. The principle of allocation is as follows:
Handle (TColStd_HSequenceOfInteger) H1 = new TColStd_HSequenceOfInteger;
// H1 has one reference and corresponds to 48 bytes of memory
{
Handle (TColStd_HSequenceOfInteger) H2;
H2 = H1; // H1 has two references
if (argc == 3)
{
Handle (TColStd_HSequenceOfInteger) H3;
H3 = H1;
// Here, H1 has three references
}
// Here, H1 has two references
}
// Here, H1 has 1 reference
}
// Here, H1 has no reference but the 48 bytes of memory are kept.
Handle (TColStd_HSequenceOfInteger) H1 = new TColStd_HSequenceOfInteger;
// Here, H1 has one reference and corresponds to the preceding 48 bytes of
// memory. In this case, there is no allocation of memory.
As cycles are objects which reference one another, memory management is impossible if the data structure contains any cycles, particularly if there are back references.
For example in a graph, objects include primitives and each one of these primitives has to know the graphic object to which it belongs (i.e. a reference to this graphic object). With normal references, the classical handle is used. With back references, a pointer is used.
As a general rule, it is advisable to allocate memory through significant blocks. In this way, the user can work with blocks of contiguous data and it facilitates memory page manager processing.