Play video using youtube player sdk about 30~40 times causes Youtube application crashes, then a DeadObjectException will raise from my app due to the death of remote process. steps to reproduce:
- launch activity and initialize YouTubePlayer
- load and play a video for a few seconds
- release YouTubePlayer and exit activity
- repeat step 1-3 about 30~40 times
OutOfMemoryError log(full logs):
08-22 12:01:01.461 E/AndroidRuntime( 3017): FATAL EXCEPTION: main
08-22 12:01:01.461 E/AndroidRuntime( 3017): Process: com.google.android.youtube.player, PID: 3017
08-22 12:01:01.461 E/AndroidRuntime( 3017): java.lang.OutOfMemoryError: Could not allocate JNI Env
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.lang.Thread.nativeCreate(Native Method)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.lang.Thread.start(Thread.java:1063)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:921)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1556)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:310)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:527)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.util.concurrent.ScheduledThreadPoolExecutor.execute(ScheduledThreadPoolExecutor.java:616)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at reo.a(SourceFile:134)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at sgh.a(SourceFile:722)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at gan.a(SourceFile:310)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at gan.b(SourceFile:338)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ApiPlayerService$2.run(SourceFile:215)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at android.os.Handler.handleCallback(Handler.java:739)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at android.os.Handler.dispatchMessage(Handler.java:95)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at android.os.Looper.loop(Looper.java:148)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at android.app.ActivityThread.main(ActivityThread.java:5417)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at java.lang.reflect.Method.invoke(Native Method)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-22 12:01:01.461 E/AndroidRuntime( 3017): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
and DeadObjectException
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): java.lang.IllegalStateException: android.os.DeadObjectException
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at gix.surfaceCreated(SourceFile:189)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.SurfaceView.updateWindow(SurfaceView.java:582)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.Choreographer.doCallbacks(Choreographer.java:670)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.Choreographer.doFrame(Choreographer.java:606)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.os.Handler.handleCallback(Handler.java:739)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.os.Handler.dispatchMessage(Handler.java:95)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.os.Looper.loop(Looper.java:148)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.app.ActivityThread.main(ActivityThread.java:5417)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at java.lang.reflect.Method.invoke(Native Method)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): Caused by: android.os.DeadObjectException
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.os.BinderProxy.transactNative(Native Method)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at android.os.BinderProxy.transact(Binder.java:503)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at com.google.android.apps.youtube.embeddedplayer.service.service.jar.ISurfaceHolderService$Stub$Proxy.a(SourceFile:110)
08-22 12:01:01.842 E/MonitoringInstrumentation( 2976): at gix.surfaceCreated(SourceFile:186)
YouTube App version is 11.29.55 , Nexus 5 emulator with Marshmallow , I've tested it with other versions of YouTube App like 10.25.57 and 10.40.58, the OOM still occurs.
At the very beginning when I encounter this issue I thought it was just caused by some incorrectly api method calls, but after so many hours research I figured out it should be a YouTube App's issue, hope someone can help me to resolve it, or at least avoid it.
The memory of process com.google.android.youtube.player
is increasing while player initialization and video playing from Memory Monitor, and many YoutubeService
instances created but not recycled from the dump file. Any idea?
I test it with a demo application based on the official YouTubeAndroidAPI sample and the OutOfMemory error occurs as well, I just replaced cueVideo(String)
by loadVideo(String)
in PlayerViewDemoActivity
for auto-playing, and added YouTubePlayer#release()
in onDestroy()
, also I added a test code based on Espresso to reproduce the memory leak issue.
here is the test code, and here for full demo code.
package com.examples.youtubeapidemo.play;
import android.os.SystemClock;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import com.examples.youtubeapidemo.YouTubeAPIDemoActivity;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
/**
* for YouTubePlayerView testing
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class PlayerViewTest {
@Rule
public ActivityTestRule<YouTubeAPIDemoActivity> mActivityTestRule =
new ActivityTestRule<YouTubeAPIDemoActivity>(YouTubeAPIDemoActivity.class);
@Test
public void testYouTubeMemoryLeaks() {
int count = 0;
while(count < 100) {
onView(withText("Simple PlayerView")).perform(click());
SystemClock.sleep(10000); // waiting for video start playing
pressBack();
count++;
Log.i("PlayerViewTest", "count: " + count);
}
}
}
com.google.android.youtube
process can be killed manually byactivityManager.killBackgroundProcesses("com.google.android.youtube");
, which requires permissionandroid.permission.KILL_BACKGROUND_PROCESSES
and must executed after a youtube player instance released. – Liwei Liu