Explicitly null MediaPeriod callbacks on release

If a MediaPeriod uses a Loadable, then there are typically
reference chains of the form:

LoadingThread[GCroot]->Loadable->MediaPeriod->Player

Where the player is the MediaPeriod callback. When the
player is released, this reference chain prevents the
player from being GC'd until Loadable cancellation
completes, which may not always be fast. This in turn
will typically prevent the application's activity from
being GC'd, since it'll normally be registered as a
listener on the player (directly or indirectly via
something like a view).

This change mitigates the issue by removing references
that the MediaPeriod holds back to the player. The
MediaPeriod will still not be eligible for GC, but the
player and application activity will be, which in most
cases will be most of the leak (in terms of size).

Issue: #4249

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=199143646
This commit is contained in:
olly 2018-06-04 09:24:05 -07:00 committed by Oliver Woodman
parent 5a6507b72d
commit 6a82f99ca1
4 changed files with 11 additions and 4 deletions

View File

@ -90,7 +90,7 @@ import java.util.Arrays;
private final Runnable onContinueLoadingRequestedRunnable;
private final Handler handler;
private Callback callback;
private @Nullable Callback callback;
private SeekMap seekMap;
private SampleQueue[] sampleQueues;
private int[] sampleQueueTrackIds;
@ -190,6 +190,7 @@ import java.util.Arrays;
}
loader.release(this);
handler.removeCallbacksAndMessages(null);
callback = null;
released = true;
eventDispatcher.mediaPeriodReleased();
}

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseIntArray;
@ -72,7 +73,7 @@ import java.util.List;
private final IdentityHashMap<ChunkSampleStream<DashChunkSource>, PlayerTrackEmsgHandler>
trackEmsgHandlerBySampleStream;
private Callback callback;
private @Nullable Callback callback;
private ChunkSampleStream<DashChunkSource>[] sampleStreams;
private EventSampleStream[] eventSampleStreams;
private SequenceableLoader compositeSequenceableLoader;
@ -150,6 +151,7 @@ import java.util.List;
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
sampleStream.release(this);
}
callback = null;
eventDispatcher.mediaPeriodReleased();
}

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.hls;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SeekParameters;
@ -57,7 +58,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private final boolean allowChunklessPreparation;
private Callback callback;
private @Nullable Callback callback;
private int pendingPrepareCount;
private TrackGroupArray trackGroups;
private HlsSampleStreamWrapper[] sampleStreamWrappers;
@ -96,6 +97,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
sampleStreamWrapper.release();
}
callback = null;
eventDispatcher.mediaPeriodReleased();
}

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.smoothstreaming;
import android.support.annotation.Nullable;
import android.util.Base64;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters;
@ -52,7 +53,7 @@ import java.util.ArrayList;
private final TrackEncryptionBox[] trackEncryptionBoxes;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private Callback callback;
private @Nullable Callback callback;
private SsManifest manifest;
private ChunkSampleStream<SsChunkSource>[] sampleStreams;
private SequenceableLoader compositeSequenceableLoader;
@ -98,6 +99,7 @@ import java.util.ArrayList;
for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
sampleStream.release();
}
callback = null;
eventDispatcher.mediaPeriodReleased();
}