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

Reply via email to