Merge remote-tracking branch 'upstream/master' into mirror-merge-10235436
[mono-project.git] / docs / gc-variables-in-c
blobc197e74205e7386e7952747a5eb0e9722b4dfe9e
1                 Handling GC allocated objects in C
3 As part of an effort to improve our GC, we need to keep track
4 precisely of where objects are stored, so we can incrementally move
5 from the current conservative GC to a more advanced precise and moving GC.
6 Previously, all global C variables were considered GC roots, but this makes
7 the GC less efficient and increases the chances false references are found
8 to GC memory, hence retaining more memory than needed.
9 We need to tell the GC that some object is supposed to be kept alive
10 as if it was referenced in a global variable.
12 For Mono embedders
13 ------------------
15 In C#, if you say:
16 class T {
17         static object o;
20 Any object which is stored in `o' is considered to be alive -- it will
21 not be collected. `o' is a member of the root set for the GC.
23 However, in C code, this is not the case. If you have:
25 static MonoObject* o = NULL;
27 The object in `o' will *NOT* be scanned.
29 If you need to store an object in a C variable and prevent it from being 
30 collected, you need to acquire a GC handle for it.
32         guint32 handle = mono_gchandle_new (my_object, TRUE);
34 TRUE means the object will be pinned, so it won't move in memory 
35 when we'll use a moving GC. You can access the MonoObject* referenced by
36 a handle with:
38         MonoObject* obj = mono_gchandle_get_target (handle);
40 When you don't need the handle anymore you need to call:
42         mono_gchandle_free (handle);
44 Note that if you assign a new object to the C var, you need to get a new 
45 handle, it's not enough to store a new object in the C var.
47 So code that looked like this:
49         static MonoObject* o = NULL;
50         ...
51         o = mono_object_new (...);
52         /* use o */
53         ...
54         /* when done to allow the GC to collect o */
55         o = NULL;
57 should now be changed to:
59         static guint32 o_handle;
60         ...
61         MonoObject *o = mono_object_new (...);
62         o_handle = mono_gchandle_new (o, TRUE);
63         /* use o or mono_gchandle_get_target (o_handle) */
64         ...
65         /* when done to allow the GC to collect o */
66         mono_gchandle_free (o_handle);
69 For Mono runtime developers
70 ---------------------------
72 There are two kinds of static vars used to store pointers to GC memory 
73 that we need to consider:
74 *) objects
75 *) other memory chunks allocated with GC_MALLOC().
77 Objects should be dealt with the GC handle support as detailed above.
78 Other items should register the static pointer as an area to be considered
79 part of the root set with the following:
81         static gpointer my_gc_data = NULL;
82         ...
83         MONO_GC_REGISTER_ROOT (my_gc_data);
84         my_gc_data = GC_MALLOC (...);
85         
86 Note that this registration is not necessary for *LOCAL* variables,
87 as they are stored on the stack. It is only necessary for global variables,
88 as they are not a part of the GC's root set.
90 Once you have done the MONO_GC_REGISTER_ROOT, the variable is just like
91 a static variable in C#. To keep an object alive, you have the variable reference
92 the GC memory, to remove the reference, set the variable to NULL.
94 As we prepare the code for a precise GC, GC_MALLOC () will not be used anymore
95 in this way in most cases: we'll have a mechanism to specify exactly where
96 references to GC memory is stored. This mechanism is now available with the new GC,
97 see usages of mono_gc_alloc_fixed (), mono_gc_register_root () and 
98 mono_gc_make_descr_from_bitmap().
99 See also docs/precise-gc for additional info.