Skip to content

JNI global ref leak: IFrameCallback NewGlobalRef not released on re-prepare / UVCPreview destroy #57

Description

@QiuYucheng2003

Summary

PreviewPrepareStream / PreviewPrepareTest create a JNI global reference for jIFrameCallback and pass it to setFrameCallback. That reference is not reliably released when the same callback is registered again, or when the UVCPreview instance is replaced/destroyed. Repeated prepare can grow the JNI global reference table.

Location

  • app/src/main/cpp/libUvc_Support/uvc_support.cpp
    • Java_humer_UvcCamera_StartIsoStreamActivityUvc_PreviewPrepareStream
    • Java_humer_UvcCamera_SetUpTheUsbDeviceUvc_PreviewPrepareTest
  • app/src/main/cpp/libUvc_Support/UVC_Camera_Saki/UVCPreview.cpp
    • UVCPreview::setFrameCallback
    • UVCPreview::~UVCPreview
    • create_UVCPreview

Details

Both JNI entry points do:

jobject frame_callback_obj = env->NewGlobalRef(jIFrameCallback);
result = setFrameCallback(..., frame_callback_obj, ...);

UVCPreview::setFrameCallback only takes ownership when the new object is not the same as mFrameCallbackObj:

if (!env->IsSameObject(mFrameCallbackObj, frame_callback_obj)) {
    if (mFrameCallbackObj)
        env->DeleteGlobalRef(mFrameCallbackObj);
    mFrameCallbackObj = frame_callback_obj;
    // ...
}

IsSameObject compares the Java objects, not the JNI handles. Calling prepare again with the same IFrameCallback creates a new global ref. That branch is skipped, so the new ref is neither stored nor DeleteGlobalRef'd.

~UVCPreview() never calls DeleteGlobalRef(mFrameCallbackObj). create_UVCPreview always news a UVCPreview and ignores the previous pointer, so the old instance (and its callback global ref) is abandoned.

DeleteGlobalRef currently exists only on the replace / missing-onFrame paths, not on destructor or same-callback re-register.

Suggested fix
1. If IsSameObject is true, DeleteGlobalRef the newly created handle (keep the existing mFrameCallbackObj).
2. In ~UVCPreview(), attach if needed and DeleteGlobalRef(mFrameCallbackObj).
3. In create_UVCPreview, destroy/stop the previous instance before allocating a new one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions