【问题标题】:Java reflection performance drops when packaged as jar打包为 jar 时,Java 反射性能下降
【发布时间】:2013-01-29 02:12:53
【问题描述】:

我真的很头疼。我尝试了一切,到处搜索。它来自我继承的那个测试 JAR 的应用程序。

(它由一个 GUI 前端和一个进行实际检查的命令行应用程序组成。GUI 通过在其自身上启动一个新的 JVM [java -cp "itself.jar" com.different 来运行命令行应用程序。 mainClass]。我知道这是一个糟糕的设计,但可能是相关的。)

无论如何,这个程序包含一些嵌套在两个 for 循环中的反射调用。问题是当应用程序被 JARed 起来时,第一次反射调用每次迭代都需要一秒钟。但是当它从类中运行时,它需要几毫秒。

实际上,这意味着这个命令:

java -jar myjar.jar

需要几个小时。

这个命令:

java -cp "...[bunch of jars];myjar.jar" com.myclasses.main

需要几分钟。

被测试的 JAR 总是一个 jar。区别仅在于测试应用程序。

非常感谢任何想法或追求的途径。谢谢!

【问题讨论】:

  • 那么myjar.jar 是测试应用程序吗?而且只有在它自己运行时才会出现性能问题,还是在所有 jar 上运行?
  • 是的,myjar.jar 是测试应用程序。要测试的 JAR 是包含在类路径中的不同 JAR。

标签: java performance class reflection jar


【解决方案1】:

您可以考虑在像 Eclipse TPTP 或 YourKit 这样的分析器下运行您的程序,并更准确地确定您的时间花在哪里。这很可能会指向您的代码中的错误,或者不太可能指向库中的错误。然后,如果你仍然无法弄清楚,请在此处发布相关代码,我们可以提供帮助。

【讨论】:

  • 已解决!我正在跟踪一些代码,发现从 JAR 运行时,一些库类是从启动 GUI 程序的类路径中获取的。一旦我删除了这个库或匹配了版本,从 jar 运行时性能错误就消失了。我不是 100% 理解它,但这就是发生的事情:GUI、应用程序和要测试的 JAR 正在使用同一个库 JAR。不知何故,当从 JAR 运行时,由 GUI 启动的 JVM,即使它不在类路径中,也使用了错误版本的 JAR(与 GUI 中的相同)。
【解决方案2】:

我不知道这是否与您的问题有关,但是此命令中的“-cp”参数将被忽略:

$ java -cp "...[bunch of jars]" -jar myjar.jar

“-cp”和“-jar”命令选项不能一起使用。可执行 JAR 文件从 JAR 清单中获取其类路径。

我不明白这如何解释您所看到的症状......但这确实意味着您尝试对可执行 JAR 执行的操作将不起作用,这可能会使您的问题变得毫无意义。


跟进

鉴于这只是问题中的一个错误......不是真正的问题......

我的建议是使用第二种形式的 java 命令运行测试;即使用 -cp 选项和类路径。很难看出它会对您的测试制度的有效性产生什么影响。

我怀疑确定性能问题的根本原因需要详细检查测试器应用程序正在做什么。

【讨论】:

  • 谢谢!这是键入问题时的疏忽。 Class-Path 确实在清单文件中,而不是命令行中。以上更新以反映这一点。
【解决方案3】:

正如其他人所提到的,您确实需要对代码进行概要分析,以了解它在哪里花费了时间。

如果我不得不猜测,我会怀疑反射工作会导致重复查找类加载器,并且从 jar 文件中提取类时加载它的速度较慢。

但同样,这只是一种预感。您需要对其进行概要分析才能确定。

【讨论】:

    猜你喜欢
    • 2010-09-30
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 2010-09-25
    相关资源
    最近更新 更多