public void BeginCheckGlobalRefCount() { // So that the JavaProxyObject.TypeRef GREF isn't counted. using (var o = new JavaObjectArray <object> (1)) o [0] = a; grefStartCount = JniEnvironment.Runtime.GlobalReferenceCount; }
public void JavaReferencedInstanceSurvivesCollection() { Console.WriteLine("JavaReferencedInstanceSurvivesCollection"); using (var t = new JniType("java/lang/Object")) { var oldHandle = IntPtr.Zero; var array = new JavaObjectArray <JavaObject> (1); var w = new Thread(() => { var v = new JavaObject(); oldHandle = v.PeerReference.Handle; array [0] = v; }); w.Start(); w.Join(); JniEnvironment.Runtime.ValueManager.CollectPeers(); GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers(); var first = array [0]; Assert.IsNotNull(JniRuntime.CurrentRuntime.ValueManager.PeekValue(first.PeerReference)); var f = first.PeerReference; var o = (JavaObject)JniRuntime.CurrentRuntime.ValueManager.GetValue(ref f, JniObjectReferenceOptions.Copy); Assert.AreSame(first, o); if (oldHandle != o.PeerReference.Handle) { Console.WriteLine("Yay, object handle changed; value survived a GC!"); } else { Console.WriteLine("What is this, Android pre-ICS?!"); } o.Dispose(); array.Dispose(); } }
public unsafe virtual int Timing_VirtualIntMethod_Marshal1Args(int[][][] value) { using (var native_array = new JavaObjectArray <int[][]> (value)) { var args = stackalloc JniArgumentValue [1]; args [0] = new JniArgumentValue(native_array); try { return(_members.InstanceMethods.InvokeVirtualInt32Method("VirtualIntMethod1Args.([[[I)I", this, args)); } finally { native_array.CopyTo(value, 0); } } }
public static JavaArray <Java.Lang.String> NewArray(string[] array) { if (array == null) { return(null); } var obj = new JavaObjectArray <Java.Lang.String>(array.Length); for (int i = 0; i < array.Length; i++) { obj[i] = new Java.Lang.String(array[i]); } return(obj); }
static void SetupLinks(JavaObjectArray <CrossReferenceBridge> array, out WeakReference <CrossReferenceBridge> root, out WeakReference <CrossReferenceBridge> child) { var a = new CrossReferenceBridge() { id = "bridge", }; var b = new CrossReferenceBridge() { id = "child", }; a.link.Add(b); array [0] = a; array [1] = b; root = new WeakReference <CrossReferenceBridge> (a, true); child = new WeakReference <CrossReferenceBridge> (b, true); }
public void CrossReferences() { using (var array = new JavaObjectArray <CrossReferenceBridge> (2)) { WeakReference <CrossReferenceBridge> root = null, child = null; var t = new Thread(() => SetupLinks(array, out root, out child)); t.Start(); t.Join(); JniEnvironment.Runtime.ValueManager.CollectPeers(); CrossReferenceBridge a, b; a = b = null; Console.WriteLine("try get A {0}", root.TryGetTarget(out a)); Console.WriteLine("try get B {0}", child.TryGetTarget(out b)); Console.WriteLine("a is null {0}", a == null); Console.WriteLine("b is null {0}", b == null); Assert.IsNotNull(a); Assert.IsNotNull(b); } }
public unsafe int VirtualIntMethod1Args(int[][][] value) { TypeRef.GetCachedInstanceMethod(ref vim1_a, "VirtualIntMethod1Args", "([[[I)I"); int r; using (var native_array = new JavaObjectArray <int[][]> (value)) { var args = stackalloc JniArgumentValue [1]; args [0] = new JniArgumentValue(native_array); if (GetType() == _members.ManagedPeerType) { r = JniEnvironment.InstanceMethods.CallIntMethod(PeerReference, vim1_a, args); } else { JniMethodInfo m = JniPeerMembers.InstanceMethods.GetMethodInfo("VirtualIntMethod1Args.([[[I)I"); r = JniEnvironment.InstanceMethods.CallNonvirtualIntMethod(PeerReference, JniPeerMembers.JniPeerType.PeerReference, m, args); } native_array.CopyTo(value, 0); } return(r); }
public unsafe void ObjectCreationTiming() { const int C = 100; var total = Stopwatch.StartNew(); Stopwatch allocTime, newObjectTime, newTime, getObjectTime; using (var Object_class = new JniType("java/lang/Object")) { var Object_init = Object_class.GetConstructor("()V"); allocTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = Object_class.AllocObject(); JniObjectReference.Dispose(ref h); } allocTime.Stop(); newObjectTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = Object_class.NewObject(Object_init, null); JniObjectReference.Dispose(ref h); } newObjectTime.Stop(); newTime = Stopwatch.StartNew(); var olist = new List <JavaObject> (C); for (int i = 0; i < C; ++i) { olist.Add(new JavaObject()); } newTime.Stop(); foreach (var o in olist) { o.Dispose(); } var strings = new JavaObjectArray <string> (100); for (int i = 0; i < 100; ++i) { strings [i] = i.ToString(); } using (strings) { var vm = JniEnvironment.Runtime; var rlist = new List <JavaObject> (C); getObjectTime = Stopwatch.StartNew(); for (int i = 0; i < C; ++i) { var h = JniEnvironment.Arrays.GetObjectArrayElement(strings.PeerReference, i); var o = vm.ValueManager.GetValue <JavaObject> (ref h, JniObjectReferenceOptions.CopyAndDispose); rlist.Add(o); } getObjectTime.Stop(); foreach (var o in rlist) { o.DisposeUnlessReferenced(); } } } total.Stop(); Console.WriteLine("## {0} Timing: Total={1} AllocObject={2} NewObject={3} `new JavaObject()`={4} JavaVM.GetObject()={5}", nameof(ObjectCreationTiming), total.Elapsed, allocTime.Elapsed, newObjectTime.Elapsed, newTime.Elapsed, getObjectTime.Elapsed); }
public void ObjectArrayEnumerationTiming() { const int C = 100; var total = Stopwatch.StartNew(); JniMethodInfo Class_getMethods; using (var t = new JniType("java/lang/Class")) { Class_getMethods = t.GetInstanceMethod("getMethods", "()[Ljava/lang/reflect/Method;"); } JniMethodInfo Method_getName; JniMethodInfo Method_getParameterTypes; JniMethodInfo Method_getReturnType; using (var t = new JniType("java/lang/reflect/Method")) { Method_getName = t.GetInstanceMethod("getName", "()Ljava/lang/String;"); Method_getParameterTypes = t.GetInstanceMethod("getParameterTypes", "()[Ljava/lang/Class;"); Method_getReturnType = t.GetInstanceMethod("getReturnType", "()Ljava/lang/Class;"); } Console.WriteLine("# {0}: Method Lookups Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); var methodHandles = new List <JavaObject> (); using (var Arrays_class = new JniType("java/util/Arrays")) { var lrefMethods = JniEnvironment.InstanceMethods.CallObjectMethod(Arrays_class.PeerReference, Class_getMethods); Console.WriteLine("# {0}: java.util.Arrays.class.getMethods() Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); var methodsTiming = Stopwatch.StartNew(); using (var methods = new JavaObjectArray <JavaObject> (ref lrefMethods, JniObjectReferenceOptions.Copy)) { foreach (var method in methods) { methodHandles.Add(method); } } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaObjectArray<JavaObject>) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); methodsTiming = Stopwatch.StartNew(); var methodHandlesGO = new List <JavaObject> (); var vm = JniEnvironment.Runtime; int len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesGO.Add(vm.ValueManager.GetValue <JavaObject> (ref v, JniObjectReferenceOptions.CopyAndDoNotRegister)); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaVM.GetObject) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); foreach (var h in methodHandlesGO) { h.DisposeUnlessReferenced(); } methodsTiming = Stopwatch.StartNew(); var methodHandlesAr = new List <JavaObject> (); len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesAr.Add(new JavaObject(ref v, JniObjectReferenceOptions.CopyAndDoNotRegister)); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JavaObject[]) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); foreach (var h in methodHandlesAr) { h.Dispose(); } methodsTiming = Stopwatch.StartNew(); var methodHandlesGR = new List <JniObjectReference> (); len = JniEnvironment.Arrays.GetArrayLength(lrefMethods); for (int i = 0; i < len; ++i) { var v = JniEnvironment.Arrays.GetObjectArrayElement(lrefMethods, i); methodHandlesGR.Add(v.NewGlobalRef()); JniObjectReference.Dispose(ref v); } methodsTiming.Stop(); Console.WriteLine("# methodHandles(JniGlobalReference) creation timing: {0} Count={1}", methodsTiming.Elapsed, methodHandles.Count); for (int i = 0; i < methodHandlesGR.Count; ++i) { var h = methodHandlesGR [i]; JniObjectReference.Dispose(ref h); methodHandlesGR [i] = h; } JniObjectReference.Dispose(ref lrefMethods); } // HACK HACK HACK // This is to workaround an error wherein constructing `pt` (below) // throws an exception because `h` is NULL, when it really can't be. // I believe that this is due to the finalizer, which likewise makes // NO SENSE AT ALL, since `p` should be keeping the handle valid! // GC.Collect (); // GC.WaitForPendingFinalizers (); foreach (var method in methodHandles) { var lookupTiming = Stopwatch.StartNew(); var n_name = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getName); var name = JniEnvironment.Strings.ToString(ref n_name, JniObjectReferenceOptions.CopyAndDispose); var n_rt = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getReturnType); using (var rt = new JniType(ref n_rt, JniObjectReferenceOptions.CopyAndDispose)) { } var parameterTiming = Stopwatch.StartNew(); var enumTime = new TimeSpan(); var lrefPs = JniEnvironment.InstanceMethods.CallObjectMethod(method.PeerReference, Method_getParameterTypes); int len = JniEnvironment.Arrays.GetArrayLength(lrefPs); var enumSw = Stopwatch.StartNew(); for (int i = 0; i < len; ++i) { var p = JniEnvironment.Arrays.GetObjectArrayElement(lrefPs, i); using (var pt = new JniType(ref p, JniObjectReferenceOptions.Copy)) { } JniObjectReference.Dispose(ref p); } JniObjectReference.Dispose(ref lrefPs); enumSw.Stop(); enumTime = enumSw.Elapsed; parameterTiming.Stop(); Console.WriteLine("## method '{0}' timing: Total={1}; Parameters={2} Parameters.Dispose={3}", name, lookupTiming.Elapsed, enumTime, parameterTiming.Elapsed); } var mhDisposeTiming = Stopwatch.StartNew(); foreach (var method in methodHandles) { method.Dispose(); } mhDisposeTiming.Stop(); Console.WriteLine("# methodHandles -> Dispose() Timing: {0}", mhDisposeTiming.Elapsed); total.Stop(); Console.WriteLine("## {0} Timing: {1}", nameof(ObjectArrayEnumerationTiming), total.Elapsed); }