2014-08-13 10:39:27 +01:00
|
|
|
<h1>Garbage Collector Interface</h1>
|
|
|
|
|
|
|
|
<h1>Public Interface</h1>
|
|
|
|
|
|
|
|
<p>The public interface of the Mono GC is fairly limited, and
|
|
|
|
its the only one that embedders should be using:
|
2016-08-03 10:59:49 +00:00
|
|
|
|
|
|
|
<h3>Garbage Collector</h3>
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
<h4><a name="api:mono_gc_collect">mono_gc_collect</a></h4>
|
2016-08-03 10:59:49 +00:00
|
|
|
<h4><a name="api:mono_gc_collection_count">mono_gc_collection_count</a></h4>
|
2014-08-13 10:39:27 +01:00
|
|
|
<h4><a name="api:mono_gc_max_generation">mono_gc_max_generation</a></h4>
|
2016-08-03 10:59:49 +00:00
|
|
|
<h4><a name="api:mono_gc_get_generation">mono_gc_get_generation</a></h4>
|
2014-08-13 10:39:27 +01:00
|
|
|
<h4><a name="api:mono_gc_get_heap_size">mono_gc_get_heap_size</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_get_used_size">mono_gc_get_used_size</a></h4>
|
2016-08-03 10:59:49 +00:00
|
|
|
<h4><a name="api:mono_gc_walk_heap">mono_gc_walk_heap</a></h4>
|
|
|
|
|
|
|
|
<h3>Reference Queues</h3>
|
|
|
|
|
|
|
|
<h4><a name="api:mono_gc_reference_queue_add">mono_gc_reference_queue_add</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_reference_queue_free">mono_gc_reference_queue_free</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_reference_queue_new">mono_gc_reference_queue_new</a></h4>
|
|
|
|
|
|
|
|
<h3>SGen Bridge</h3>
|
|
|
|
|
|
|
|
<p>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.
|
|
|
|
|
|
|
|
<p>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.
|
|
|
|
|
|
|
|
<p>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.
|
|
|
|
|
|
|
|
<p>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
|
2016-11-10 13:04:39 +00:00
|
|
|
wishes to be kept alive. The value of `is_alive` will be
|
|
|
|
ignored on any SCCs which lack bridges.
|
2016-08-03 10:59:49 +00:00
|
|
|
|
|
|
|
<p>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.
|
|
|
|
|
|
|
|
<p>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.
|
|
|
|
|
|
|
|
<div class="mapi-header">
|
|
|
|
enum {
|
2016-11-10 13:04:39 +00:00
|
|
|
SGEN_BRIDGE_VERSION = 5
|
2016-08-03 10:59:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<h4><a name="api:mono_gc_register_bridge_callbacks">mono_gc_register_bridge_callbacks</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wait_for_bridge_processing">mono_gc_wait_for_bridge_processing</a></h4>
|
|
|
|
|
|
|
|
<h3>Write Barriers</h3>
|
|
|
|
|
2019-12-10 18:00:56 +00:00
|
|
|
<p>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.
|
|
|
|
|
2016-08-03 10:59:49 +00:00
|
|
|
<h4><a name="api:mono_gc_wbarrier_arrayref_copy">mono_gc_wbarrier_arrayref_copy</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_generic_nostore">mono_gc_wbarrier_generic_nostore</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_generic_store">mono_gc_wbarrier_generic_store</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_generic_store_atomic">mono_gc_wbarrier_generic_store_atomic</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_object_copy">mono_gc_wbarrier_object_copy</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_set_arrayref">mono_gc_wbarrier_set_arrayref</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_set_field">mono_gc_wbarrier_set_field</a></h4>
|
|
|
|
<h4><a name="api:mono_gc_wbarrier_value_copy">mono_gc_wbarrier_value_copy</a></h4>
|
2014-08-13 10:39:27 +01:00
|
|
|
|