相对于其他运行时环境(例如CPython),JVM(特别是Sun的实现)为什么启动速度较慢?我的印象是这主要与大量库被加载而不管它们是否需要有关,但这似乎不应该需要10年来解决。
话说回来,JVM的启动时间与Windows上的CLR比较如何?Mono的CLR呢?
更新:我特别关心在Unix中常见的小型工具链使用情况。Java现在是否适合这种风格?无论Java的启动开销如何,它是为每个Java进程都加上吗,还是仅在第一个进程中表现出开销?
相对于其他运行时环境(例如CPython),JVM(特别是Sun的实现)为什么启动速度较慢?我的印象是这主要与大量库被加载而不管它们是否需要有关,但这似乎不应该需要10年来解决。
话说回来,JVM的启动时间与Windows上的CLR比较如何?Mono的CLR呢?
更新:我特别关心在Unix中常见的小型工具链使用情况。Java现在是否适合这种风格?无论Java的启动开销如何,它是为每个Java进程都加上吗,还是仅在第一个进程中表现出开销?
这里是维基百科关于该问题的说法(含一些参考资料)。
看起来大部分时间都花在从磁盘加载数据(类)上了(即启动时间受 I/O 限制)。
请注意以下解决方案:
JVM有两种机制可以加快启动速度。 第一种是类数据共享机制,自Java 6 Update 21以来已得到支持(只适用于HotSpot客户端VM,并且据我所知仅适用于串行垃圾收集器)
要激活它,您需要设置 -Xshare (在某些实现中: -Xshareclasses )JVM选项。
要了解更多信息,请访问: 类数据共享
第二种机制是Java快速启动程序。 它允许在操作系统启动期间预加载类,请参见: Java Quick Starter 以获取更多详细信息。
话虽如此,至少在我的机器上(Linux x86_64 with 64bit kernel),32位HotSpot版本支持客户端和服务器模式(通过-client和-server标志),但默认为服务器模式,而64位版本仅支持服务器模式。
这取决于启动时你正在做什么。如果你运行Hello World应用程序,在我的机器上只需要0.15秒。
然而,Java更适合作为客户端或服务器/服务运行,这意味着启动时间不像连接时间(约0.025毫秒)或往返响应时间(<< 0.001毫秒)那样重要。
有很多原因:
jar
文件我不确定CLR是否也是这样,但我认为它通常更快,因为它会缓存程序集的本地版本以供下次使用(因此不需要JIT)。CPython启动更快,因为它是一个解释器,并且我IRC,不进行JIT。
所有具有丰富类型系统(例如Java或CLR)的虚拟机与那些在C或C++中发现的不太丰富的系统相比,都不会瞬间实例化。这主要是因为虚拟机中发生了很多事情,许多类被初始化并被运行系统所需。初始化系统的快照确实有所帮助,但将该图像重新加载到内存中仍然需要成本等。
一个简单的hello world样式的一行类与主要仍需要加载和初始化很多。验证类需要进行大量依赖性检查和验证,所有这些都需要执行时间和许多CPU指令。另一方面,C程序不会执行任何此类操作,仅需要一些指令,然后调用打印机函数即可。