* contrib/hbct/doc/en/*.txt
* contrib/hbgt/doc/en/hbgt.txt
* contrib/hbmisc/doc/en/*.txt
* contrib/hbziparc/doc/en/hbziparc.txt
* contrib/rddads/doc/en/adsfuncs.txt
* doc/en/*.txt
! space after comma
! unicode fix
! minor corrections
* extras/template/tests/hbmk.hbm
* cleaned recently added comment
281 lines
9.1 KiB
Plaintext
281 lines
9.1 KiB
Plaintext
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Document
|
|
$NAME$
|
|
The Garbage Collector
|
|
$CATEGORY$
|
|
Document
|
|
$ONELINER$
|
|
Readme for Harbour Garbage Collect Feature
|
|
$DESCRIPTION$
|
|
The garbage collector uses the following logic:
|
|
- first collect all memory allocations that can cause garbage;
|
|
- next scan all variables if these memory blocks are still referenced.
|
|
|
|
Notice that only arrays, objects and codeblocks are collected because
|
|
these are the only datatypes that can cause self-references ( a[ 1 ] := a )
|
|
or circular references ( a[ 1 ] := b; b[ 1 ] := c; c[ 1 ] := a ) that
|
|
cannot be properly deallocated by simple reference counting.
|
|
|
|
Since all variables in harbour are stored inside some available tables
|
|
(the eval stack, memvars table and array of static variables) then checking
|
|
if the reference is still alive is quite easy and doesn't require any
|
|
special treatment during memory allocation. Additionaly the garbage
|
|
collector is scanning some internal data used by harbour objects
|
|
implementation that also stores some values that can contain memory
|
|
references. These data are used to initialize class instance variables
|
|
and are stored in class shared variables.
|
|
|
|
In special cases when the value of a harbour variable is stored internally
|
|
in some static area (at C or assembler level), the garbage collector will
|
|
be not able to scan such values since it doesn't know their location. This
|
|
could cause some memory blocks to be released prematurely. To prevent the
|
|
premature deallocation of such memory blocks the static data have to store
|
|
a pointer to the value created with hb_itemNew() function.
|
|
Example:
|
|
static HB_ITEM s_item; /* this item can be released by the GC */
|
|
|
|
static PHB_ITEM pItem; /* this item will be maintained correctly */
|
|
pItem = hb_itemNew( hb_param( 1, IT_BLOCK ) );
|
|
|
|
However, scanning of all variables can be a time consuming operation. It
|
|
requires that all allocated arrays have to be traversed through all their
|
|
elements to find more arrays. Also all codeblocks are scanned for detached
|
|
local variables they are referencing. For this reason, looking for unreferenced
|
|
memory blocks is performed during the idle states.
|
|
|
|
The idle state is a state when there is no real application code
|
|
executed. For example, the user code is stopped for 0.1 of a second
|
|
during Inkey(0.1) - Harbour is checking the keyboard only
|
|
during this time. It leaves however quite enough time for
|
|
many other background tasks. One such background task can be looking
|
|
for unreferenced memory blocks.
|
|
|
|
Allocating memory </par>
|
|
-----------------
|
|
|
|
The garbage collector collects memory blocks allocated with hb_gcAlloc()
|
|
function calls. Memory allocated by hb_gcAlloc() should be released with
|
|
hb_gcFree() function.
|
|
|
|
The garbage collecting </par>
|
|
----------------------
|
|
|
|
During scanning of unreferenced memory the GC is using a mark & sweep
|
|
algorithm. This is done in three steps:
|
|
|
|
1) mark all memory blocks allocated by the GC with unused flag;
|
|
|
|
2) sweep (scan) all known places and clear unused flag for memory
|
|
blocks that are referenced there;
|
|
|
|
3) finalize collecting by deallocation of all memory blocks that are
|
|
still marked as unused and that are not locked.
|
|
|
|
To speed things up, the mark step is simplified by swapping the meaning
|
|
of the unused flag. After deallocation of unused blocks all still alive
|
|
memory blocks are marked with the same 'used' flag so we can reverse
|
|
the meaning of this flag to 'unused' state in the next collecting.
|
|
All new or unlocked memory blocks are automatically marked as 'unused'
|
|
using the current flag, which assures that all memory blocks are marked
|
|
with the same flag before the sweep step will start.
|
|
See hb_gcCollectAll() and hb_gcItemRef()
|
|
|
|
Calling the garbage collector from harbour code </par>
|
|
-----------------------------------------------
|
|
|
|
The garbage collector can be called directly from the harbour code.
|
|
This is usefull in situations where there is no idle states available
|
|
or the application is working in the loop with no user interaction
|
|
and there is many memory allocations.
|
|
See hb_gcAll() for explanation of how to call this function from your
|
|
harbour code.
|
|
$SEEALSO$
|
|
hb_gcAlloc(), hb_gcFree(), hb_gcCollectAll(), hb_gcItemRef(), hb_gcAll(), hb_idleState()
|
|
$END$
|
|
*/
|
|
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Function
|
|
$NAME$
|
|
hb_gcAlloc()
|
|
$CATEGORY$
|
|
API
|
|
$SUBCATEGORY$
|
|
Garbage Collector
|
|
$ONELINER$
|
|
Allocates memory that will be collected by the garbage collector.
|
|
$SYNTAX$
|
|
#include "hbapi.h"
|
|
void * hb_gcAlloc( HB_SIZE nSize,
|
|
PHB_GARBAGE_FUNC pCleanupFunc );
|
|
$ARGUMENTS$
|
|
<ulSize> Requested size of memory block
|
|
|
|
<pCleanupFunc> Pointer to HB_GARBAGE_FUNC function that will be called
|
|
directly before releasing the garbage memory block or NULL. This
|
|
function should release all other memory allocated and stored inside
|
|
the memory block. For example, it releases all items stored inside
|
|
the array. The functions receives a single parameter: the pointer
|
|
to memory allocated by hb_gcAlloc().
|
|
$RETURNS$
|
|
The pointer to allocated memory or it generates an internal
|
|
unrecoverable error.
|
|
$DESCRIPTION$
|
|
hb_gcAlloc() is used to allocate the memory that will be tracked
|
|
by the garbage collector. It allows to properly release memory
|
|
in case of self-referencing or cross-referencing harbour level
|
|
variables.
|
|
Memory allocated with this function should be released with
|
|
hb_gcFree() function or it will be automatically deallocated
|
|
by the GC if it is not locked or if it is not referenced by some
|
|
harbour level variable.
|
|
$STATUS$
|
|
C
|
|
$COMPLIANCE$
|
|
H
|
|
$PLATFORMS$
|
|
All
|
|
$SEEALSO$
|
|
hb_gcFree()
|
|
$END$
|
|
*/
|
|
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Function
|
|
$NAME$
|
|
hb_gcFree()
|
|
$CATEGORY$
|
|
API
|
|
$SUBCATEGORY$
|
|
Garbage Collector
|
|
$ONELINER$
|
|
Releases the memory that was allocated with hb_gcAlloc().
|
|
$SYNTAX$
|
|
void hb_gcFree( void * pMemoryPtr );
|
|
$ARGUMENTS$
|
|
<pMemoryPtr> The pointer to memory for release. This memory
|
|
pointer have to be allocated with hb_gcAlloc() function.
|
|
$RETURNS$
|
|
Nothing.
|
|
$DESCRIPTION$
|
|
hb_gcFree() is used to deallocate the memory that was
|
|
allocated with the hb_gcAlloc() function.
|
|
$STATUS$
|
|
C
|
|
$COMPLIANCE$
|
|
H
|
|
$PLATFORMS$
|
|
All
|
|
$SEEALSO$
|
|
hb_gcAlloc()
|
|
$END$
|
|
*/
|
|
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Function
|
|
$NAME$
|
|
hb_gcCollectAll()
|
|
$CATEGORY$
|
|
API
|
|
$SUBCATEGORY$
|
|
Garbage Collector
|
|
$ONELINER$
|
|
Scans all memory blocks and releases the garbage memory.
|
|
$SYNTAX$
|
|
void hb_gcCollectAll( void );
|
|
$ARGUMENTS$
|
|
None.
|
|
$RETURNS$
|
|
Nothing.
|
|
$DESCRIPTION$
|
|
This function scans the eval stack, the memvars table, the array
|
|
of static variables and table of created classes for referenced
|
|
memory blocks. After scanning all unused memory blocks and blocks
|
|
that are not locked are released.
|
|
$STATUS$
|
|
C
|
|
$COMPLIANCE$
|
|
H
|
|
$PLATFORMS$
|
|
All
|
|
$SEEALSO$
|
|
hb_gcAlloc(), hb_gcFree()
|
|
$END$
|
|
*/
|
|
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Function
|
|
$NAME$
|
|
hb_gcItemRef()
|
|
$CATEGORY$
|
|
API
|
|
$SUBCATEGORY$
|
|
Garbage Collector
|
|
$ONELINER$
|
|
Marks the memory to prevent deallocation by the garbage collector.
|
|
$SYNTAX$
|
|
void hb_gcItemRef( PHB_ITEM pItem );
|
|
$ARGUMENTS$
|
|
<pItem> The pointer to item structure that will be scanned. The
|
|
passed item can be of any datatype although arrays, objects
|
|
and codeblocks are scanned only. Other datatypes don't require
|
|
locking so they are simply ignored.
|
|
$RETURNS$
|
|
Nothing.
|
|
$DESCRIPTION$
|
|
The garbage collector uses hb_gcItemRef() function during
|
|
scanning of referenced memory pointers. This function checks the
|
|
type of passed item and scans recursively all other memory blocks
|
|
referenced by this item if it is an array, an object or a codeblock.
|
|
|
|
NOTE: This function is reserved for the garbage collector only. It
|
|
cannot be called from the user code - calling it can cause
|
|
unpredicted results (memory blocks referenced by the
|
|
passed item can be released prematurely during the closest
|
|
garbage collection).
|
|
$STATUS$
|
|
C
|
|
$COMPLIANCE$
|
|
H
|
|
$PLATFORMS$
|
|
All
|
|
$SEEALSO$
|
|
hb_gcAlloc(), hb_gcFree()
|
|
$END$
|
|
*/
|
|
|
|
/* $DOC$
|
|
$TEMPLATE$
|
|
Procedure
|
|
$NAME$
|
|
hb_gcAll()
|
|
$CATEGORY$
|
|
API
|
|
$SUBCATEGORY$
|
|
Garbage Collector
|
|
$ONELINER$
|
|
Scans the memory and releases all garbage memory blocks.
|
|
$SYNTAX$
|
|
hb_gcAll()
|
|
$ARGUMENTS$
|
|
None
|
|
$DESCRIPTION$
|
|
This function releases all memory blocks that are considered
|
|
as the garbage.
|
|
$STATUS$
|
|
Harbour
|
|
$COMPLIANCE$
|
|
H
|
|
$PLATFORMS$
|
|
All
|
|
$SEEALSO$
|
|
hb_gcCollectAll()
|
|
$END$
|
|
*/
|