Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Fixed memory leaks (cleaner version) #135

Open
wants to merge 45 commits into
base: master
Choose a base branch
from

Conversation

kkawai
Copy link

@kkawai kkawai commented Apr 12, 2017

As stated before, the biggest memory leak saver is converting the anonymous CallbackBridge class in CameraView to be static. And reference the CameraView within CallbackBridge to be a WeakReference.
Another is using the application context to get the camera manager, instead of the activity context. Memory leaks have been reported if you use the activity context to:
(CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
So, we want the context to be the application context.
Other than that, I just cleaned up the code so there are as few differences as possible with google cameraview.

if (Build.VERSION.SDK_INT < 21) {
mImpl = new Camera1(mCallbacks, preview);
} else if (Build.VERSION.SDK_INT < 23) {
mImpl = new Camera2(mCallbacks, preview, context);
mImpl = new Camera2(mCallbacks, preview, context.getApplicationContext());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important for memory leak fix is to pass the application context here.

} else {
mImpl = new Camera2Api23(mCallbacks, preview, context);
mImpl = new Camera2Api23(mCallbacks, preview, context.getApplicationContext());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important for memory leak fix is to pass the application context here.

@@ -152,6 +153,9 @@ protected void onDetachedFromWindow() {
mDisplayOrientationDetector.disable();
}
super.onDetachedFromWindow();
if (mCallbacks != null && mCallbacks.mCallbacks != null) {
mCallbacks.mCallbacks.clear();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important for memory leak: clear out any callbacks to ensure no extra references are held

@@ -407,13 +411,16 @@ public void takePicture() {
mImpl.takePicture();
}

private class CallbackBridge implements CameraViewImpl.Callback {
private static class CallbackBridge implements CameraViewImpl.Callback {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important for memory leak: non-static inner classes implicitly hold references to their parent. This was causing a big leak. Making it static fixes that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually experience memory leaks due to this?
It seems to me CallbackBridge won't be an issue. It does hold a reference to CameraView, but it won't outlive the CameraView.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My team uses LeakCanary to detect memory leaks. Unfortunately, the warnings were not false-positives. When I implemented these simple changes, the warnings went away.
It might be helpful to integrate LeakCanary into the demo app. It only takes a few minutes and run the app a few times to find out the leaks.

private WeakReference<CameraView> cameraView;

CallbackBridge(CameraView cameraView) {
this.cameraView = new WeakReference<>(cameraView);
Copy link
Author

@kkawai kkawai Apr 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important for memory leak: Since CallbackBridge is now static, we must pass the CameraView. Within CallbackBridge only hold a weak reference to it.

@@ -9,6 +9,7 @@ buildscript {

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.1.0'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you suspend these changes in build scripts?

@@ -407,13 +411,16 @@ public void takePicture() {
mImpl.takePicture();
}

private class CallbackBridge implements CameraViewImpl.Callback {
private static class CallbackBridge implements CameraViewImpl.Callback {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually experience memory leaks due to this?
It seems to me CallbackBridge won't be an issue. It does hold a reference to CameraView, but it won't outlive the CameraView.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants