Java JVM 8 更新后声音明显变慢
Java Sound dramatically slower after JVM 8 update
我的应用程序在启动时加载了一堆音频剪辑。它使用 java.applet.Applet.newAudioClip(URL audioFileURL)
加载同一文件夹中的文件。我可以看到这个函数基本上是一个包装器来获取 JavaSoundAudioClip
objects
直到昨天,我用 JDK 7 编译了 JAR,并用 JRE 版本 7 update 45 启动了它。然后我更新到版本 8 update 31。
现在,每个音频的加载时间比以前长十倍(每个 0.2 秒,现在是 2 到 3 秒)
同样的行为发生在不同的硬件配置上。 OS是64bit Windows7,Java7和8运行环境都是32bit。
深入调试,我发现最慢的方法是 AudioSystem.getAudioInputStream
, AudioSystem.isLineSupported
, AudioSystem.getLine
不应该涉及音频格式:我尝试了 OGG 和 WAV,结果相同。
两个 JVM 的设置相同
编辑:即使我无法在临时制作的小程序中重现该问题。 Java 8 确实较慢,但只有 10% 的因素。我的应用程序和我正在使用的库必须有一些特别的东西与音频系统 and/or 它的流冲突。知道了会第一时间更新
Java8介绍了垃圾收集器的一些新技术。
由于您正在将 data/Ojects 加载到 VM 中,它们可能会被触发以执行并发扫描和并行压缩。
建议您调整 JVM GC 参数。
-XX:ConcGCThreads=n 并发垃圾收集器将使用的线程数。默认值随JVM所在平台不同而不同运行.
-XX:InitiatingHeapOccupancyPercent=n 启动并发 GC 周期的(整个)堆占用百分比。它被 GC 使用,根据整个堆的占用情况触发并发 GC 周期,而不仅仅是其中一个代(例如 G1)。值 0 表示 'do constant GC cycles'。默认值为 45。
-XX:ParallelGCThreads=n 设置垃圾收集器并行阶段使用的线程数。默认值因 JVM 所在的平台而异 运行。
-XX:ConcGCThreads=n 并发垃圾收集器将使用的线程数。默认值随JVM所在平台不同而不同运行.
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
Kindly, let me know if GC tuning helped, I am not able to replicate
your scenario, but it would be an interesting fact to learn what was
causing it !
终于,我找到了导致问题的原因。我使用 jar-in-jar-loader(据我所知,它等同于 Eclipse 选项 "Package required libraries into generated JAR")在我的应用程序中包含库 jar。到目前为止,这从未对性能产生任何明显影响。
但是对于 Java 8,我经历了这种巨大的减速。使用 jconsole 监控应用程序我注意到它经常被阻塞等待 zip deflate 操作,因此 JRE 版本 8 中一定发生了一些变化,现在对 jars inside jars 的优化较少。
我决定选择提取所有库 jar,然后将它们打包到我的应用程序 jar 中。
我的应用程序在启动时加载了一堆音频剪辑。它使用 java.applet.Applet.newAudioClip(URL audioFileURL)
加载同一文件夹中的文件。我可以看到这个函数基本上是一个包装器来获取 JavaSoundAudioClip
objects
直到昨天,我用 JDK 7 编译了 JAR,并用 JRE 版本 7 update 45 启动了它。然后我更新到版本 8 update 31。
现在,每个音频的加载时间比以前长十倍(每个 0.2 秒,现在是 2 到 3 秒)
同样的行为发生在不同的硬件配置上。 OS是64bit Windows7,Java7和8运行环境都是32bit。
深入调试,我发现最慢的方法是 AudioSystem.getAudioInputStream
, AudioSystem.isLineSupported
, AudioSystem.getLine
不应该涉及音频格式:我尝试了 OGG 和 WAV,结果相同。
两个 JVM 的设置相同
编辑:即使我无法在临时制作的小程序中重现该问题。 Java 8 确实较慢,但只有 10% 的因素。我的应用程序和我正在使用的库必须有一些特别的东西与音频系统 and/or 它的流冲突。知道了会第一时间更新
Java8介绍了垃圾收集器的一些新技术。 由于您正在将 data/Ojects 加载到 VM 中,它们可能会被触发以执行并发扫描和并行压缩。 建议您调整 JVM GC 参数。
-XX:ConcGCThreads=n 并发垃圾收集器将使用的线程数。默认值随JVM所在平台不同而不同运行.
-XX:InitiatingHeapOccupancyPercent=n 启动并发 GC 周期的(整个)堆占用百分比。它被 GC 使用,根据整个堆的占用情况触发并发 GC 周期,而不仅仅是其中一个代(例如 G1)。值 0 表示 'do constant GC cycles'。默认值为 45。
-XX:ParallelGCThreads=n 设置垃圾收集器并行阶段使用的线程数。默认值因 JVM 所在的平台而异 运行。 -XX:ConcGCThreads=n 并发垃圾收集器将使用的线程数。默认值随JVM所在平台不同而不同运行.
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
Kindly, let me know if GC tuning helped, I am not able to replicate your scenario, but it would be an interesting fact to learn what was causing it !
终于,我找到了导致问题的原因。我使用 jar-in-jar-loader(据我所知,它等同于 Eclipse 选项 "Package required libraries into generated JAR")在我的应用程序中包含库 jar。到目前为止,这从未对性能产生任何明显影响。
但是对于 Java 8,我经历了这种巨大的减速。使用 jconsole 监控应用程序我注意到它经常被阻塞等待 zip deflate 操作,因此 JRE 版本 8 中一定发生了一些变化,现在对 jars inside jars 的优化较少。
我决定选择提取所有库 jar,然后将它们打包到我的应用程序 jar 中。