Hi Jon,
To complicate things a little more I have a custom view for the list that
contains a bitmap and a couple of text views.
After taking a closer look to the log output I noticed two things:
- There's a huge amount of JavaObjectWrapper<T> instances in the list of JNI
global refs.
- There's also a little less huge amount (400) of TextView instances in the
list of JNI global refs.
That led me to the conclusion that I am a little bit sloppy in the way I manage
references to UI widgets.
It's true that I have need of a lot of textviews, because my list is rather
complicated, but 400 is a bit excessive :P
I did the following to fix the problem:
TextView someTextView = view.FindViewById<TextView>(Resource.Id.SomeId);
// Set properties here
someTextView.Dispose(); <-- That releases the JNI global ref for the
textview.
Also I created a list of JavaObjectWrapper<T> and assigned that to the custom
ListAdapter.
It sounds silly, but when I convert a normal object into a
JavaObjectWrapper<T> in the GetItem(int position) method, a new instance gets
created multiple times for the same .NET object. Resulting in a whopping 852
instances of the JavaObjectWrapper<T> class each holding a JNI global ref. By
making the choice of base object a little more explicit I saved myself a couple
of hundred global references.
Memory management is a little bit tricky with both a Java GC and .NET GC
combined with JNI :P
I wonder though if I could return a single dummy object in GetItem(int
position) for each call instead of the objects from the internal list.
That could reduce the amount of JNI references from a list of items to just 1.
Kind regards,
Willem Meints
-----Oorspronkelijk bericht-----
Van: [email protected]
[mailto:[email protected]] Namens Jonathan Pryor
Verzonden: Sunday, August 28, 2011 3:15 PM
Aan: Discussions related to Mono for Android
Onderwerp: Re: [mono-android] Excessive JNI global references
On Aug 28, 2011, at 6:34 AM, Willem Meints wrote:
> In my app I'm getting a crash with the promising message: "Excessive JNI
> global references".
> The runtime is right, I have too many of them and I do want to fix the issue,
> however there's one little hiccup.
...
> Is there any way I can fix this problem? For example, can I use another
> technique to implement the GetItem method of the BaseAdapter class?
This bears further research, but I _think_ you may be able to use
Android.Runtime.JavaList. JavaList is backed by a java.util.ArrayList in the
Dalvik vm; thus, you'll need a GREF for the JavaList instance itself, but
anything stored within the JavaList shouldn't take out any additional GREFs.
(In theory; again, this bears testing.)
I would suggest that you try using e.g. ArrayAdapter (or a subclass of
ArrayAdapter), and for the ArrayAdapter(Context, int, IList) constructor
providing your JavaList instance. (This may require subclassing ArrayAdapter if
you don't want to provide the otherwise required TextView id; see the
ArrayAdapter documentation for details [0].) If you use ArrayAdapter and/or
ArrayAdapter<T>, you may also be able to avoid using the JavaObjectWrapper<T>
type, and let ArrayAdapter<T> handle the type conversions for you (though I'm
not entirely sure this would work).
Thanks,
- Jon
[0] http://docs.mono-android.net/index.aspx?link=T%3aAndroid.Widget.ArrayAdapter
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid