为什么JVM启动缓慢?

时间:2009-05-09 21:47:01

标签: java jvm performance startup

与CPython等其他运行时相比,JVM(特别是Sun的实现)的运行速度有多慢?我的印象是,无论是否需要,它主要与一大堆图书馆的装载有关,但这似乎不需要花费10年的时间来修复。

想想看,JVM的启动时间与Windows上的CLR相比如何? Mono的CLR怎么样?

更新:我特别关注链接在一起的小型实用程序的用例,这在Unix中很常见。 Java现在适合这种风格吗?无论Java发生什么样的启动开销,它是否会为每个Java进程加起来,还是仅仅为第一个进程显示开销?

8 个答案:

答案 0 :(得分:19)

这是what Wikipedia has to say on the issue(有一些参考资料)。

似乎大部分时间都是从磁盘加载数据(类)(即启动时间是I / O限制)。

答案 1 :(得分:8)

请注意一些解决方案:

有两种机制可以更快地启动JVM。 第一个是类数据共享机制,自Java 6 Update 21以来一直受支持(仅限HotSpot客户端虚拟机,据我所知只有串行垃圾收集器)

要激活它,您需要设置 -Xshare (在某些实现上: -Xshareclasses )JVM选项。

要详细了解您可能会访问的功能: Class data sharing

第二种机制是Java Quick Starter。它允许在OS启动期间预加载类,请参阅: Java Quick Starter了解更多详情。

答案 2 :(得分:5)

使用1.6(Java 6)客户端JVM运行一个简单的Java应用程序似乎在我的机器上是即时的。 Sun已经尝试调整客户端JVM以便更快地启动(并且客户端JVM是默认的),因此如果您不需要大量额外的jar文件,那么启动应该很快。

答案 3 :(得分:4)

如果你正在使用Sun的HotSpot for x86_64(64位编译),请注意当前的实现只能在服务器模式下工作,也就是说,它预先编译它加载的每个类都有完全优化,而32位版本也支持客户端模式,通常会推迟优化并优化大多数CPU密集型部件,但启动时间更短。

参见例如:

话虽如此,至少在我的机器上(具有64位内核的Linux x86_64),32位HotSpot版本支持客户端和服务器模式(通过-client和-server标志),但默认为服务器模式,而64位版本仅支持服务器模式。

答案 4 :(得分:3)

这实际上取决于你在启动时做了什么。如果您运行Hello World应用程序,我的计算机需要0.15秒。

然而,Java更适合作为客户端或服务器/服务运行,这意味着启动时间不如连接时间(约0.025毫秒)或往返时间响应时间(<< 0.001毫秒)。

答案 5 :(得分:1)

有很多原因:

  • 要加载大量jar
  • 验证(确保代码不做恶事)
  • JIT(及时编译)开销

我不确定CLR,但我认为它通常更快,因为它会在下次缓存本机版本的程序集(因此它不需要JIT)。 CPython开始得更快,因为它是一个解释器,而IIRC,不做JIT。

答案 6 :(得分:1)

除了已经提到的内容(加载类,特别是压缩的JAR);在HotSpot编译常用字节码之前以解释模式运行;和HotSpot编译开销,JDK类本身也进行了相当多的一次性初始化。 许多优化都是为了支持更长时间运行的系统,而启动速度则不那么令人担忧。

对于unix样式的流水线操作:你当然不想多次启动和重新启动JVM。这不会有效。而是应该在JVM中进行工具链接。除非从JVM中启动此类工具,否则这不能与非Java Unix工具轻松混合。

答案 7 :(得分:0)

与较不丰富的系统(如C或C ++中的系统)相比,所有具有丰富类型系统(如Java或CLR)的VM都不会是实时的。这主要是因为VM中发生了很多事情,很多类都被初始化并且是正在运行的系统所需要的。初始化系统的快照确实有帮助,但将图像加载到内存等仍然需要花费。

一个简单的hello world世界风格的一个班轮类与一个主要仍然需要很多加载和初始化。验证类需要大量的依赖性检查和验证,所有这些都需要花费时间和许多CPU指令来执行。另一方面,C程序不会执行任何这些操作,并且会执行一些指令,然后调用打印机功能。