我正在使用java制作游戏。我正在快速测试音频播放,以确保它有效。以下代码是主要方法。
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JFXPanel();
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
//assets grabs a Media object
new MediaPlayer(Assets.getMedia("aBstracT - Vivacious Vagabonds.mp3")).play();
//cannot create an anonymous inner class of media player
new Object() {
@Override
public void finalize() {
System.out.println("Garbage collected");
}
};
我很困惑地发现音乐在40秒时始终停止。我的猜测是垃圾收集(我意识到我没有引用任何媒体对象),我在打印输出中确认了这一点。
我的问题如下:
为什么40秒?垃圾收集何时发生?我发现这很奇怪,并且一直认为只有当有太多未使用的对象(或者其他东西,我真的不知道)时,JVM才会尝试进行垃圾收集。
第二,有什么办法可以将JVM标记为垃圾收集对象吗?在决定是否应该从内存中删除之前,JVM寻找对每个对象的引用似乎效率低下。在垃圾收集出错的情况下,我也担心内存泄漏。
提前致谢。
答案 0 :(得分:1)
回答您的问题:无法保证GC会随时进入。如果不使用对象,可以实现GC永不发生。它完全依赖于实现,Sun和Oracle都实现了许多不同的GC实现。在您的情况下,使用您的JVM版本,它将在40秒后启动。添加更多内存可能会更改该计时器。在Android上运行可能会改变它,升级到JDK 9可能会改变它。
您的第二个问题也是相同的:您通过删除对它的所有引用来标记GC的对象。局部变量为null的所有常见设置完全没用。退出方法时,将删除变量以及对象的引用。 GC不会出错。如果是这样,它就是JVM中的一个错误,并且是一个比你想象的更大的问题: - )
如果您担心GC性能,那么您并不孤单。但说实话,这不再是一个大问题。您需要确定需要分配的内存以避免GC冻结您的应用程序。要更好地了解GC机制,请查看此处:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
要解决您的问题,您需要在媒体播放器上保留一个参考。