我的应用程序在启动时加载了一堆音频剪辑。它使用java.applet.Applet.newAudioClip(URL audioFileURL)
加载文件,这些文件位于同一文件夹中。我可以看到这个函数基本上是获取JavaSoundAudioClip
个对象的包装器
直到昨天,我用JDK 7编译JAR并使用JRE版本7更新45启动它。然后我更新到版本8更新31.
现在,每个音频的加载时间比以前长10倍(每个0.2秒,现在是2到3秒)
在不同的硬件配置上发生了相同的行为。操作系统是64位Windows 7,Java 7和8运行时环境都是32位。
深入调试,我发现速度最慢的方法是AudioSystem.getAudioInputStream
,AudioSystem.isLineSupported
,AudioSystem.getLine
不应涉及音频格式:我尝试了同样的结果OGG和WAV。
两个JVM的设置相同
编辑:即使我无法在ad-hoc的小程序中重现这个问题。 Java 8确实较慢,但只有10%的因素。我的应用程序必须有一些特别的东西,而我正在使用的库与音频系统和/或其流有冲突。我一发现就会更新。答案 0 :(得分:7)
最后,我发现了导致问题的原因。我使用jar-in-jar-loader(据我所知,它相当于Eclipse选项“将所需的库打包到生成的JAR中”)在我的应用程序中包含库jar。到目前为止,这对性能没有任何明显的影响 但是使用Java 8,我经历了这种巨大的放缓。使用jconsole监视应用程序我注意到它经常被阻塞等待zip deflate操作,因此JRE版本8中的某些内容必须已更改,现在对于jar中的jar进行了优化。
我决定选择提取所有库jar,然后将它们打包到我的应用程序jar中。
答案 1 :(得分:3)
Java 8引入了一些垃圾收集器的新技术。 由于您正在将数据/对象加载到VM中,因此它们可能会被触发以执行并发扫描和并行压缩。 建议你调整JVM GC参数。
-XX:ConcGCThreads = n并发垃圾收集器将使用的线程数。默认值因运行JVM的平台而异。
-XX:InitiatingHeapOccupancyPercent = n启动并发GC循环的(整个)堆占用百分比。它由GC使用,它基于整个堆的占用而不仅仅是一代(例如,G1)占用并发GC循环。值0表示“执行恒定GC循环”。默认值为45。
-XX:ParallelGCThreads = n设置垃圾收集器并行阶段使用的线程数。默认值因运行JVM的平台而异。 -XX:ConcGCThreads = n并发垃圾收集器将使用的线程数。默认值因运行JVM的平台而异。
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
请告诉我,如果GC调整有帮助,我无法复制 你的场景,但要了解它是一个有趣的事实 造成它!