Garbage Collection
Your application must keep hard references to the media player instances that you create. If you do not do this, your media player will become unexpectedly garbage collected at some future indterminate time and you will see a fatal crash eventually or immediately depending on how lucky you are.
Why?
A fatal crash occurs because in the background the media player that you created is running a native thread outside of your Java application and that native thread calls back in to a vlcj media player. If the vlcj media player has been garbage collected that native thread has nowhere to go so crashes.
You have to keep the hard reference to the media player because there is nothing else that keeps your media player reference alive - the native code knows nothing about Java applications.
When?
Consider this code:
You don't need to understand the whole thing right now, but look at where the
mediaPlayerComponent
instance is created. It is a local variable inside the
constructor. This code will run and the media will indeed start playing. The
constructor will exit and the media player will keep playing for a while.
However, when the garbage collector runs there is nothing keeping the
mediaPlayerComponent
reference alive - it is no longer "reachable" so the
media player instance is discarded and garbage collected even though it is
still running!
How to Fix?
Here we have moved the mediaPlayerComponent
from being a method-local
variable to being a class field variable. This means that the media player
instance will still be reachable after the constructor exits, and seemingly our
problem is solved.
But there is still a, less obvious, flaw with this code...
Look where the BetterCode
instance is created - the instance is never
actually assigned to a variable. As before, the media will play for a while but
eventually (or maybe even shortly) the garbage collector will run and find that
the class instance itself is no longer reachable so will discard it - when that
happens, the mediaPlayerComponent
instance in the class field variable also
becomes no longer reachable and so it too is discarded. The end result is a
fatal Java Virtual Machine crash.
How To Really Fix?
We must keep a reference to the class instance too, here the goodCode
variable retains a hard reference to our class instance.
Summary
This tutorial has explained the need for 'pinning' your media player instances in memory to prevent unwanted garbage collection.
There are different ways to achieve the same effect, do whatever works for your application, but the point is you must be aware of this.
Depending on your application you may not even have to do anything - for the
common case of using an EmbeddedMediaPlayerComponent
(as discussed in this
series of tutorials so far) you usually have a JFrame
instance that is
keeping a reference to the media player component instance (you added the media
player component to the frame) and this is enough to keep the instance alive
and prevent it from being garbage collected.
Depending on a number of factors, like your operating system, your Java Virtual Machine version, your application Java Virtual Machine memory configuration and garbage collection configuration you may encounter this problem immediately, a short time later, or some considerable time later lulling you into a false sense of security. You must be aware of this issue.