JVM 8 更新后 Java 声音明显变慢

2022-09-04 03:42:08

我的应用程序在启动时加载一堆音频剪辑。它用于加载位于同一文件夹中的文件。我可以看到这个函数基本上是一个获取对象的包装器。java.applet.Applet.newAudioClip(URL audioFileURL)JavaSoundAudioClip

直到昨天,我用JDK 7编译了JAR,并使用JRE版本7更新45启动了它。然后我更新到版本8更新31。
现在,每个音频的加载时间比以前长十倍(每个音频0.2秒,现在在2到3秒之间)
相同的行为发生在不同的硬件配置上。操作系统是64位Windows 7,Java 7和8运行时环境都是32位。

在调试中深入挖掘,我发现速度最慢的方法是, ,AudioSystem.getAudioInputStreamAudioSystem.isLineSupportedAudioSystem.getLine

不应该涉及音频格式:我尝试了OGG和WAV,结果相同。

两个 JVM 的设置相同

编辑:即使我无法在临时制作的小程序中重现问题。Java 8确实更慢,但只有10%的系数。我的应用程序和我使用的库必须有一些与音频系统和/或其流冲突的东西。一旦我发现,我会立即更新。


答案 1

最后,我找出了导致问题的原因。我使用jar-in-jar-loader(据我所知,它相当于Eclipse选项“将所需的库打包到生成的JAR中”)在我的应用程序中包含库jar。到目前为止,这从未对性能产生任何明显的影响。
但是在Java 8中,我经历了这种巨大的放缓。使用jconsole监视应用程序时,我注意到它经常被阻止等待zip放气操作,因此JRE版本8中必须发生了一些变化,该版本现在对jars中的jar进行了较少的优化。

我决定选择提取所有库 jar,然后将它们打包到我的应用程序 jar 中。


答案 2

Java 8 引入了一些垃圾回收器的新技术。由于要将数据/Oject 加载到 VM 中,因此可能会触发它们以执行并发扫描和并行压缩。建议您调整 JVM GC 参数。

-XX:ConcGCThreads=n 并发垃圾回收器将使用的线程数。缺省值因运行 JVM 的平台而异。

-XX:启动HeapOccupancyPercent=n启动并发GC周期的(整个)堆占用的百分比。它由基于整个堆的占用情况触发并发GC周期的GC使用,而不仅仅是其中一代(例如G1)。值为 0 表示“执行恒定的 GC 循环”。默认值为 45。

-XX:ParallelGCThreads=n 设置垃圾回收器并行阶段使用的线程数。缺省值因运行 JVM 的平台而异。-XX:ConcGCThreads=n 并发垃圾回收器将使用的线程数。缺省值因运行 JVM 的平台而异。

http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

请让我知道如果GC调整有帮助,我无法复制您的场景,但了解导致它的原因将是一个有趣的事实!


推荐