hb_gcItemRef()

hb_gcItemRef()

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).

Compliance

Harbour

Platforms

All

Files

src/vm/garbage.c

Seealso

hb_gcAlloc(), hb_gcFree()

hb_gcFree()

hb_gcFree()

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.

Examples

      See src/vm/arrays.c

Compliance

Harbour

Platforms

All

Files

src/vm/garbage.c

Seealso

hb_gcAlloc()

hb_gcCollectAll()

hb_gcCollectAll()

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.

Compliance

Harbour

Platforms

All

Files

src/vm/garbage.c

Seealso

hb_gcAlloc(), hb_gcFree()

hb_gcAlloc()

hb_gcAlloc()

Allocates memory that will be collected by the garbage collector.

Syntax

      #include "hbapi.h"
      void * hb_gcAlloc( HB_SIZE nSize,
      HB_GARBAGE_FUNC_PTR 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.

Examples

      See src/vm/arrays.c

Compliance

Harbour

Platforms

All

Files

src/vm/garbage.c

Seealso

hb_gcFree()

hb_gcAll()

HB_GCALL()

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.

Compliance

Harbour

Platforms

All

Files

src/vm/garbage.c

Seealso

hb_gcCollectAll()

The Garbage Collector

The Garbage Collector

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

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

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

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()

Harbour Extensions

Harbour Extensions

Harbour Extensions

Description

Language extensions:

* Class generation and management.

CA-Cl*pper only allowed creation of objects from a few standard classes.

In Harbour, you can create your own classes–complete with Methods, Instance Variables, Class Variables and Inheritance. Entire applications can be designed and coded in Object Oriented style.

* @<FunctionName>()

Returns the pointer (address) to a function.

The returned value is not useful to application-level programming, but is used at a low level to implement object oriented coding. (Internally, a class method is a static function and there is no symbol for it, so it is accessed via its address).

* Class HBGetList

Object oriented support for GetLists management.

* ProcName() support for class Method names.

Class Methods can be retrieved from the call stack.

* Memory() has new return values.

See hbmemory.ch

* Transform() –> new function in format string

@0 Make a zero padded string out of the number.

* SToD() –> dDate

New function that converts a yyyymmdd string to a Date value.

* Optional Compile Time STRONG TYPE declaration (and compile time TYPE MISMATCH warnings)

Example: LOCAL/STATIC Var AS …

* The Harbour debugger provides new interesting classes:

– Class TDbWindow could be the foundation for a generic multiplatform

– Class TForm

– Class TDbMenu implement both pulldown and popup menus.

RTL enhanced functionality:

– Directory( <cMask>, <cFlags>, <lEightDotThree> )

The 3rd parameter is a Harbour (optional) parameter and indicates that on those platforms that support long filenames, that you wish to receive what would be considered the dos equivalant 8.3 name. Could affect Adir() and Dir if they were modified to take advantage of it – currently, they will return long names if the os supports it.

– HB_DiskSpace( <nDrive>, <nType> )

The second parameter is a Harbour (optional) parameter and indicates the type of diskinfo being requested. See en/diskspac.txt for info.