This causes a temporary resource leak, but not a permanent one. Eventually, the garbage collector will release all the memory and resources. But you might want to call release()
to avoid errors, because "eventually" might not be soon enough.
I've verified on an Android 4.4.2 device that when a streaming AudioTrack
is no longer referenced anywhere, and garbage collection is run, it will be finalized, whether or not stop()
has been called.
In Android's source code (I looked at Android N's), finalize()
calls the same native function as release()
does:
static void android_media_AudioTrack_finalize(JNIEnv *env, jobject thiz) {
//ALOGV("android_media_AudioTrack_finalize jobject: %x\n", (int)thiz);
android_media_AudioTrack_release(env, thiz);
}
So yes, eventually, the resources will be released without you needing to call release()
explicitly.
But this could be a problem if too many AudioTrack
s are created in a short period of time. Creating and dereferencing them in a loop:
for (...) {
new AudioTrack(...);
}
I eventually get this error in my logs:
E/AudioTrack-JNI: Error initializing AudioTrack
E/android.media.AudioTrack: Error code -20 when initializing AudioTrack.
E/AudioTrack: AudioFlinger could not create track, status: -12
Garbage collection didn't fix this; it wasn't run because there was enough normal heap memory available. Other resources, of the type that release()
releases, ran out. This error didn't trigger immediate garbage collection. Calling release()
, of course, fixes this problem.