我有一个用Java编写的应用程序,我想知道在达到static void int main(String args)
之前需要多长时间以及它在这个阶段正在做什么,我该怎么做?
我知道微软有一个名为MPGO(Manager profile guided optimisation)的工具,Java有类似的工具吗?
在Java应用程序内部测量启动时间的简单方法:
import java.lang.management.ManagementFactory;
public class Test {
public static void main(String[] args) {
long currentTime = System.currentTimeMillis();
long vmStartTime = ManagementFactory.getRuntimeMXBean().getStartTime();
System.out.println(currentTime - vmStartTime);
}
}
您可以使用 JVMTI代理跟踪虚拟机事件,例如类加载、垃圾回收、方法编译等。这里有一个我制作的简单代理 - vmtrace(以及 Windows的编译dll)。
运行java -agentpath:path\to\vmtrace.dll Main
,事件跟踪将被打印到stderr
中:
[0.00000] VMTrace started
[0.00182] Dynamic code generated: flush_icache_stub
[0.00187] Dynamic code generated: get_cpu_info_stub
[0.00519] Dynamic code generated: getCPUIDNameInfo_stub
[0.00524] Dynamic code generated: forward exception
[0.00526] Dynamic code generated: call_stub
...
[0.01182] Loading class: java/lang/Object
[0.01198] Loading class: java/lang/String
[0.01206] Loading class: java/io/Serializable
...
[0.05620] VM initialized
[0.05664] Class prepared: java/lang/invoke/MethodHandle
[0.05672] Loading class: java/lang/invoke/MethodHandleImpl
[0.05732] Class prepared: java/lang/invoke/MethodHandleImpl
[0.05738] Loading class: java/lang/invoke/MethodHandleImpl$1
[0.05743] Class prepared: java/lang/invoke/MethodHandleImpl$1
[0.05755] Loading class: java/lang/invoke/MethodHandleImpl$2
[0.05759] Loading class: java/util/function/Function
[0.05768] Class prepared: java/util/function/Function
...
另一种测量启动时间的方法是使用自Java 9以来可用的ProcessHandle:
public static void main(String[] args) {
var currentTimeMillis = System.currentTimeMillis();
var processStartTime = ProcessHandle.current().info().startInstant().get();
System.out.println(currentTimeMillis - processStartTime.toEpochMilli());
}
-Xverbose:codegen
更多细节在这里https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/slow_start.html#wp1083972
更新 5/9/2016
根据我们以下的对话。 jstat将提供关于类加载器的基于时间的统计信息。必须通过执行获取虚拟机id(vmid)
jps
使用此ID可以执行以下操作
jstat -class {vmid} 1000 10
这将在十秒钟内每秒提供一次类加载器的快照。
trace
函数以解决这个问题。最好将代理输出与应用程序输出分开 - 您可以将文件名指定为代理参数。 - apanginvmtrace
,使其输出同步,并记录了 [VM destroyed]。 - apangin