Java性能问题

时间:2011-02-18 13:54:39

标签: java performance

我正在对我编写的应用程序进行基准测试。我在循环中将我的应用程序通过基准测试10次(获得10个结果而不是1个)。每次,第一次迭代似乎比其余的迭代花费大约50-100毫秒。

这是否与JIT编译器有关,是否可以做任何事情来“重置”状态,以便在所有迭代中包含初始“滞后”?

5 个答案:

答案 0 :(得分:3)

要对长时间运行的应用程序进行基准测试,您应该允许初始化(第一次传递),这是因为必须加载类,必须生成代码,在Web应用程序中JSP编译为servlet等.JIT当然也扮演它的角色。如果垃圾收集发生,有时通行证可能需要更长的时间。

答案 1 :(得分:1)

这可能是由于JIT开始引起的,但是你可能想要忽略最初的延迟。至少大多数基准尝试,因为它严重扭曲了统计数据。

您不能“编译”已编译的代码,但可以使用-Xint命令行开关完全关闭编译。

答案 2 :(得分:1)

由于JIT,第一遍可能总是较慢。由于可能的增量编译或更好的分支预测,我甚至期望在进行更多运行时看到差异。

对于基准测试,请遵循其他答案中给出的建议(除非我不会关闭JIT,因为您的应用程序在生产环境中使用JIT运行)。

在任何情况下都使用分析器,例如JVisualVM(包含在JDK中)。

答案 3 :(得分:0)

您的代码中可能存在某些结构,例如singletons,它们只初始化一次并消耗系统资源。例如,如果您正在使用数据库连接池,则可能就是这种情况。此外,它是Java类初始化所需的时间。出于这些原因,我认为你应该抛弃第一个值而只保留其余值。

答案 4 :(得分:0)

  

这与JIT编译器有关吗

可能是的,虽然还有其他潜在的“滞后”来源:

  • 引导JVM并创建初始类加载器。
  • 读取并加载应用程序的类以及使用的库类。
  • 初始化课程。
  • JIT编译。
  • 堆热身效应;例如堆的开销最初太小了。 (这可能导致GC比正常运行更频繁......直到堆达到与应用程序的峰值工作集大小相匹配的大小。)
  • 虚拟内存预热效果;例如当JVM增加进程地址空间并分配物理页时,会产生操作系统开销。
  

...并且有什么可以做“重置”状态,以便你得到所有迭代中包含的初始“滞后”?

除了重新启动JVM之外,你无能为力。


但是,你可以采取一些措施来消除这些“滞后”的来源;例如转换JIT编译,使用较大的初始堆大小,并在空闲的机器上运行。

此外,@Joachim提供的链接值得彻底阅读。