public override void FinalizePeer(IJavaPeerable value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (Logger.LogGlobalRef) { JNIEnv._monodroid_gref_log($"Finalizing handle {value.PeerReference}\n"); } // FIXME: need hash cleanup mechanism. // Finalization occurs after a test of java persistence. If the // handle still contains a java reference, we can't finalize the // object and should "resurrect" it. if (value.PeerReference.IsValid) { GC.ReRegisterForFinalize(value); } else { RemovePeer(value, (IntPtr)value.JniIdentityHashCode); value.SetPeerReference(new JniObjectReference()); value.Finalized(); } }
public override void FinalizePeer(IJavaPeerable value) { var h = value.PeerReference; var o = Runtime.ObjectReferenceManager; // MUST NOT use SafeHandle.ReferenceType: local refs are tied to a JniEnvironment // and the JniEnvironment's corresponding thread; it's a thread-local value. // Accessing SafeHandle.ReferenceType won't kill anything (so far...), but // instead it always returns JniReferenceType.Invalid. if (!h.IsValid || h.Type == JniObjectReferenceType.Local) { if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString()); } RemovePeer(value); value.SetPeerReference(new JniObjectReference()); value.Finalized(); return; } RemovePeer(value); if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Finalizing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString()); } value.SetPeerReference(new JniObjectReference()); JniObjectReference.Dispose(ref h); value.Finalized(); }