On Jan 3, 2012, at 5:17 AM, Steven Pack wrote:
> Now... How do I actually clean up? If I deterministically call GC.Collect(), 
> the GREF count is stable. If I don't, it just grows and grows (on the 
> emulator only).

No, it grows and grows everywhere, devices just have a higher limit of around 
52000. :-)

As for limiting GREF usage, there are three answers:

1. Dispose of objects when you're doing using them. In your original example:

        public void UpdateSuggestions (IList<string> suggestions)
        {
                // Note: ONLY use `using` if `lvlSuggestions` is a native type
                using (var lvSuggestions = 
FindViewById<ListView>(Resource.Id.suggestion_listview)) {
                        var adapter = new 
CustomisedTypefaceArrayAdapter<String>(_registry.CustomTypeface, this, 
Resource.Layout.list_item, suggestions);
                        lvSuggestions.Adapter = adapter;
                }
        }

The above reduces the lifetime of the Managed Callable Wrapper (MCW) instance 
referred to by `lvlSuggestions`, allowing the GREF to be released at the end of 
the `using` block.

As the note states, this should NOT be used with your own subclasses IFF they 
need to survive outside the scope of the `using` block, as 
Java.Lang.Object.Dispose() will break the mapping between the managed object 
and the corresponding Java-side object. For "shallow" MCW instances, this is 
fine (we'll just create a new MCW the next time the Java object is surfaced in 
managed code), but for custom types with custom fields, Dispose()ing of them 
means that the next time the Java object is surfaced, you'll either (i) get an 
exception because because your type is missing the (IntPtr, JniHandleOwnership) 
constructor, or (ii) "lose" all your instance data fields because you'll be 
dealing with a different instance.

2. Reuse objects when appropriate. This is mostly aimed at the 
BaseAdapter.GetView(int position, View convertView, ViewGroup parent) method. 
The `convertView` parameter should be reused if it isn't null, as this will 
reduce the number of object allocations.

3. Call GC.Collect() ~regularly. In many circumstances this is required anyway, 
as Mono's GC doesn't know anything about the Dalvik GC, so an e.g. 
Android.Graphics.Bitmap instance will be ~32 bytes in size, even though it's 
holding on to a 10MB image file in Java. We have some ideas on how to improve 
this, but they won't be implemented soon, and it likely can't work for 
everything. For many things, explicit GC.Collect()s will be required.

 - Jon

_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to