Description
In part, revert commit 1caf077 (which provides the logic for JNI local references by default), and follow Xamarin.Android in making JNI Global References the default semantic.
As per Xummit discussions, a "local reference by default" worldview doesn't "work" for developers; it adds a useless complication with myriad knock-on effects.
For example, Android is limited to only 512 JNI local references at a time, which means you could only have 512 JavaObject
subclass instances at a time unless JavaObject.RegisterWithVM()
were invoked (to turn the JNI local reference into a global reference). Furthermore, since handles are now GC SafeHandle constructs, it may require a GC to actually collect them, prolonging lifetimes and making an Android crash more likely.
(We already had to move away from the "JNI Local References" semantic in commit 972c5bc by giving the instance a JNI global reference during construction, so that when invoking a constructor, if the Java constructor invoked any overridden virtual methods, the correct instance could be looked up to perform the method dispatch.)
Instead of JNI Local References by default, make them JNI Global References by default, and add:
partial JavaVM {
public T UnregisterInstance<T>(T value)
where T : IJavaObject, IJavaObjectEx;
}
(Additionally, remove RegisterWithVM()
/etc. from JavaObject
; let's try to keep that API as small as possible.)
Add a JniObjectReferenceOptions.DoNotRegister
value, and if specified don't register the instance with the VM.
Adds thread-safety; allows creation of temporary instances w/o registration, removing a "window of mapping".
Related: Xamarin.Android Bug #25995