mono-api-gc.html

# Garbage Collector Interface

# Public Interface

The public interface of the Mono GC is fairly limited, and its the only one that embedders should be using:

### Garbage Collector

`mono_gc_collect`
Syntax
void mono_gc_collect (int generation)

Parameters

generation | GC generation identifier

Description

Perform a garbage collection for the given generation, higher numbers mean usually older objects. Collecting a high-numbered generation implies collecting also the lower-numbered generations. The maximum value for generation can be retrieved with a call to `mono_gc_max_generation`, so this function is usually called as:

`mono_gc_collect (mono_gc_max_generation ());`
`mono_gc_collection_count`
Syntax
int mono_gc_collection_count (int generation)

Parameters

generation | a GC generation number

Return value
the number of garbage collections
Description

Get how many times a garbage collection has been performed for the given generation number.

`mono_gc_max_generation`
Syntax
int mono_gc_max_generation (void)

Return value
the maximum generation number.
Description

Get the maximum generation number used by the current garbage collector. The value will be 0 for the Boehm collector, 1 or more for the generational collectors.

`mono_gc_get_generation`
Syntax
int mono_gc_get_generation (MonoObject *object)

Parameters

object | a managed object

Return value
a garbage collector generation number
Description

Get the garbage collector's generation that object belongs to. Use this has a hint only.

`mono_gc_get_heap_size`
Syntax
int64_t mono_gc_get_heap_size (void)

Return value
the size of the heap in bytes
Description

Get the amount of memory used by the garbage collector.

`mono_gc_get_used_size`
Syntax
int64_t mono_gc_get_used_size (void)

Return value
the amount of memory used in bytes
Description

Get the approximate amount of memory used by managed objects.

`mono_gc_walk_heap`
Syntax
int mono_gc_walk_heap (int flags, MonoGCReferences callback, void *data)

Parameters

flags | flags for future use
callback | a function pointer called for each object in the heap
data | a user data pointer that is passed to callback

Return value
a non-zero value if the GC doesn't support heap walking
Description
This function can be used to iterate over all the live objects in the heap; for each object, callback is invoked, providing info about the object's location in memory, its class, its size and the objects it references. For each referenced object its offset from the object address is reported in the offsets array. The object references may be buffered, so the callback may be invoked multiple times for the same object: in all but the first call, the size argument will be zero. Note that this function can be only called in the `MONO_GC_EVENT_PRE_START_WORLD` profiler event handler.

### Reference Queues

`mono_gc_reference_queue_add`
Syntax
gboolean mono_gc_reference_queue_add (MonoReferenceQueue *queue, MonoObject *obj, void *user_data)

Parameters

queue | the queue to add the reference to.
obj | the object to be watched for collection
user_data | parameter to be passed to the queue callback

Return value
`FALSE` if the queue is scheduled to be freed.
Description

Queue an object to be watched for collection, when the obj is collected, the callback that was registered for the queue will be invoked with user_data as argument.

`mono_gc_reference_queue_free`
Syntax
void mono_gc_reference_queue_free (MonoReferenceQueue *queue)

Parameters

queue | the queue that should be freed.

Description

This operation signals that queue should be freed. This operation is deferred as it happens on the finalizer thread.

After this call, no further objects can be queued. It's the responsibility of the caller to make sure that no further attempt to access queue will be made.
`mono_gc_reference_queue_new`
Syntax
MonoReferenceQueue* mono_gc_reference_queue_new (mono_reference_queue_callback callback)

Parameters

callback | callback used when processing collected entries.

Return value
the new queue.
Description

Create a new reference queue used to process collected objects. A reference queue let you add a pair of (managed object, user data) using the `mono_gc_reference_queue_add` method.

Once the managed object is collected callback will be called in the finalizer thread with 'user data' as argument.

The callback is called from the finalizer thread without any locks held. When an AppDomain is unloaded, all callbacks for objects belonging to it will be invoked.

### SGen Bridge

The bridge is a mechanism for SGen to let clients override the death of some unreachable objects. We use it in monodroid to do garbage collection across the Mono and Java heaps.

The client can designate some objects as "bridged", which means that they participate in the bridge processing step once SGen considers them unreachable, i.e., dead. Bridged objects must be registered for finalization.

When SGen is done marking, it puts together a list of all dead bridged objects and then does a strongly connected component analysis over their object graph. That graph will usually contain non-bridged objects, too.

The output of the SCC analysis is passed to the `cross_references()` callback. It is expected to set the `is_alive` flag on those strongly connected components that it wishes to be kept alive. The value of `is_alive` will be ignored on any SCCs which lack bridges.

In monodroid each bridged object has a corresponding Java mirror object. In the bridge callback it reifies the Mono object graph in the Java heap so that the full, combined object graph is now instantiated on the Java side. Then it triggers a Java GC, waits for it to finish, and checks which of the Java mirror objects are still alive. For those it sets the `is_alive` flag and returns from the callback.

The SCC analysis is done while the world is stopped, but the callback is made with the world running again. Weak links to bridged objects and other objects reachable from them are kept until the callback returns, at which point all links to bridged objects that don't have `is_alive` set are nulled. Note that weak links to non-bridged objects reachable from bridged objects are not nulled. This might be considered a bug.
enum { SGEN_BRIDGE_VERSION = 5 }; typedef enum { /* Instances of this class should be scanned when computing the transitive dependency among bridges. E.g. List of object*/ GC_BRIDGE_TRANSPARENT_CLASS, /* Instances of this class should not be scanned when computing the transitive dependency among bridges. E.g. String*/ GC_BRIDGE_OPAQUE_CLASS, /* Instances of this class should be bridged and have their dependency computed. */ GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS, /* Instances of this class should be bridged but no dependencies should not be calculated. */ GC_BRIDGE_OPAQUE_BRIDGE_CLASS, } MonoGCBridgeObjectKind; typedef struct { mono_bool is_alive; /* to be set by the cross reference callback */ int num_objs; MonoObject *objs [MONO_ZERO_LEN_ARRAY]; } MonoGCBridgeSCC; typedef struct { int src_scc_index; int dst_scc_index; } MonoGCBridgeXRef; typedef struct { int bridge_version; /* * Tells the runtime which classes to even consider when looking for * bridged objects. If subclasses are to be considered as well, the * subclass check must be done in the callback. */ MonoGCBridgeObjectKind (*bridge_class_kind) (MonoClass *klass); /* * This is only called on objects for whose classes * `bridge_class_kind()` returned `XXX_BRIDGE_CLASS`. */ mono_bool (*is_bridge_object) (MonoObject *object); void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs); } MonoGCBridgeCallbacks;
`mono_gc_register_bridge_callbacks`
Syntax
void mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks)

`mono_gc_wait_for_bridge_processing`
Syntax
void mono_gc_wait_for_bridge_processing (void)

### Write Barriers

SGen is a concurrent and generational GC, features which require tracking changes to the state of the heap. This is achieved through write barriers. Whenever native code is changing the state of the heap by storing references into another managed object, it needs to do it using this write barrier API.
`mono_gc_wbarrier_arrayref_copy`
Syntax
void mono_gc_wbarrier_arrayref_copy (void* dest_ptr, /*const*/ void* src_ptr, int count)

Parameters

dest_ptr | destination slot address
src_ptr | source slot address
count | number of references to copy

Description
Copies count references from one array to another, executing a write barrier if needed.
`mono_gc_wbarrier_generic_nostore`
Syntax
void mono_gc_wbarrier_generic_nostore (void* ptr)

Description
Executes a write barrier for an address, informing the GC that the reference stored at that address has been changed.
`mono_gc_wbarrier_generic_store`
Syntax
void mono_gc_wbarrier_generic_store (void* ptr, MonoObject* value)

Parameters

ptr | address of field
obj | object to store

Description
Stores the value object inside the field represented by ptr, executing a write barrier if needed.
`mono_gc_wbarrier_generic_store_atomic`
Syntax
void mono_gc_wbarrier_generic_store_atomic (void *ptr, MonoObject *value)

Description
Same as `mono_gc_wbarrier_generic_store` but performs the store as an atomic operation with release semantics.
`mono_gc_wbarrier_object_copy`
Syntax
void mono_gc_wbarrier_object_copy (MonoObject* obj, MonoObject *src)

Parameters

obj | destination object
src | source object

Description
Copies contents of src to obj, executing any necessary write barriers.
`mono_gc_wbarrier_set_arrayref`
Syntax
void mono_gc_wbarrier_set_arrayref (MonoArray *arr, void* slot_ptr, MonoObject* value)

Parameters

arr | array containing the destination slot
slot_ptr | address of slot inside the array
value | reference to the object to be stored

Description
Stores an object reference inside an array of objects, executing a write barrier if needed.
`mono_gc_wbarrier_set_field`
Syntax
void mono_gc_wbarrier_set_field (MonoObject *obj, void* field_ptr, MonoObject* value)

Parameters

obj | object containing the destination field
field_ptr | address of field inside the object
value | reference to the object to be stored

Description
Stores an object reference inside another object, executing a write barrier if needed.