Skip to content

Fix possible premature collection #5405

Description

@jonpryor

See: https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JavaObject.cs#L35

The problem with new JavaObject(obj).Handle is that there is a window wherein the JavaObject is collected after the .Handle property is accessed, but before .Handle is returned to Java code, which would "normally" keep the JavaObject instance alive.

Related:

This statement should instead be:

return JNIEnv.ToLocalJniHandle (new JavaObject (obj));

Additionally, JNIEnv.ToLocalJniHandle() needs to add a GC.KeepAlive(): https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JNIEnv.cs#L746-L754

It should be:

public static IntPtr ToLocalJniHandle (IJavaObject? value)
{
	if (value == null)
		return IntPtr.Zero;
	var ex = value as IJavaObjectEx;
	if (ex != null)
		return ex.ToLocalJniHandle ();
	try {
		return NewLocalRef (value.Handle);
	}
	finally {
		GC.KeepAlive (value);
	}
}

This will ensure that value isn't likewise GC'd immediately after the .Handle access but before NewLocalRef() is invoked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions