当Java反射被打包成jar文件时,性能会下降。

7

我这里有一个头疼的问题。我已经尝试了所有方法,搜索了所有地方。这个问题来自于我继承的一个测试JAR文件的应用程序。

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

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

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

java -jar myjar.jar

需要翻译的内容:

需要几个小时才能完成。

这个命令:

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

只需要几分钟。

被测试的JAR文件始终是一个JAR文件,区别仅在于测试应用程序。

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


所以 myjar.jar 是测试应用程序?只有在它自己运行时才会出现性能问题,还是所有的 jar 包都会出现这个问题? - matts
是的,myjar.jar 是测试应用程序。要测试的 JAR 是包含在类路径中的另一个 JAR。 - Michael Steinberg
3个回答

1
你可以考虑在Eclipse TPTPYourKit等性能分析器下运行程序,更准确地确定时间花费在哪里。这很可能会指向代码错误,或者稍微不太可能指向库中的错误。如果你仍然无法解决问题,请在此处发布相关代码,我们可以提供帮助。

1
已解决!我正在追踪一些代码,发现当从JAR文件运行时,某些库类是从启动GUI程序的类路径中获取的。一旦我删除了这个库或匹配了版本,从jar运行时性能bug就消失了。我并不完全理解它,但这就是发生的事情:相同的库JAR被GUI、应用程序和要测试的JAR使用。不知何故,在从JAR运行时,由GUI启动的JVM即使它没有在类路径中,也使用了此JAR的错误版本(与GUI相同的版本)。 - Michael Steinberg

0

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

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

"-cp"和"-jar"命令选项不能同时使用。可执行的JAR文件从JAR清单中获取其类路径。

我不明白这如何解释您所看到的症状...但这意味着您尝试使用可执行的JAR文件所做的事情将无法实现,这可能使您的问题无效。


后续

考虑到这只是问题中的一个错误,而不是真正的问题...

我的建议是使用Java命令的第二种形式运行测试;即使用-cp选项和类路径。很难看出它如何影响您的测试方案的有效性。

我怀疑确定性能问题的根本原因将需要详细检查测试应用程序正在执行的操作。


谢谢!在输入问题时疏忽了。Class-Path确实在清单文件中,而不是命令行中。已更新上面的内容以反映这一点。 - Michael Steinberg

0

正如其他人所提到的,您确实需要对代码进行分析以确定它花费时间的位置。

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

但再次强调,这只是一个猜测。您需要进行分析以确保。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接