C++
Acad::ErrorStatus reclaimMemoryFromErasedObjects( const AcDbObjectIdArray& erasedObjects );
Description
This member function deletes the objects underneath the input object ids and performs some related cleanup.
The object ids in the input array must already be erased, and they should reside in the invoked database. Objects owned by the objects listed in the input array will be erased unless they already are, and their memory also reclaimed.
The following table describes the error conditions and their reasons:
Error Code | Reason |
---|---|
Acad::eInvalidOpenState | There can be no active transactions, regardless of whether the entities in the input list are in them or not. If there are any active transactions, then none of the input objects will be deleted and no memory reclaimed. |
Acad::eWasNotErased | If there are any objects whose memory cannot be reclaimed because they are not erased. |
Acad::eInvalidOpenState | If an object is not entirely closed. |
Acad::eWrongDatabase | If objects in the array are not from the invoked database object. |
Acad::ePermanentlyErased | If an object has already had its memory reclaimed. |
Note that if some objects do not meet all the required conditions but others do, the ones meeting the requirements will be deleted and their memory reclaimed. If multiple error conditions are found, then the returned status will be the first encountered. However, subsequent objects in the input array will be processed, and deleted if they meet all the requirements.
If Acad::eOk is not returned, and you want to know which objects' memory was successfully reclaimed, attempt to open each of the objects in the input array. If the error status returned is Acad::ePermanentlyErased, then its memory was successfully reclaimed, otherwise it wasn't.
All deleted objects and memory will be restored upon undo, and re-deleted upon redo, by use of their DWG filing members.
Parameters
Parameters | Description |
---|---|
erasedObjects | An array of object ids whose memory is to be reclaimed by deleting their objects. All object ids in the array must correspond to erased objects, which must be entirely closed. |
Notes
For performance reasons, it is better to call this function as infrequently as possible with as many objects in the input array as possible, because there is a performance overhead that varies with the size of the overall database with each call, regardless of the number of objects whose memory is to be reclaimed.
If there are entities in the array, it is faster to group them by their owning block, although not required.
Also note that before being deleted, the object state is saved for Undo, of which some will remain in memory. It should be negligible for a huge drawing, but disabling Undo should eliminate this aspect of residual memory usage.
Note also that there is a residual amount of memory per object that cannot be reclaimed which can approach 10% of simple objects such as lines and circles that is associated with the object id and handle.
Beware of Rogue Classes: This function performs cleanup for all AcDbObject classes that are supplied with all flavors of AutoCAD. Some specialized object classes may require cleanup beyond the scope of this function. Such requirements cannot be anticipated in this function, so the developer who utilizes this function is advised to beware, and to thoroughly test the stability of the set of custom classes they anticipate to input to this function. They may have to wrap calls to this function in a function that performs additional cleanup for specific classes.
Example
// Get the current space Block Table Record. AcDbObjectId btrId = acdbHostApplicationServices()->workingDatabase()->currentSpaceId(); AcDbBlockTableRecord* pBtr; if (Acad::eOk != acdbOpenObject(pBtr, btrId, AcDb::kForRead)) return; AcDbObjectIdArray erasedObjects; ASSERT(erasedObjects.length() == 0); // Iterate over the Block Table record, looking for erased entities... AcDbBlockTableRecordIterator* btri; pBtr->newIterator(btri); // we are looking for erased entities, so we have to explicitly // say so on start and step for (btri->start(true, false); !btri->done(); btri->step(true, false)) { AcDbObjectId id; btri->getEntityId(id); erasedObjects.append(id); } delete btri; pBtr->close(); // reclaim the memory acdbHostApplicationServices()->workingDatabase()-> reclaimMemoryFromErasedObjects(erasedObjects);