2 Slow JVM Startup

This chapter provides information to help you diagnose and troubleshoot problems that cause the JRockit JVM to start slowly.

This chapter contains the following topics:

2.1 Possible Causes for Slow JVM Startup

An application might seem slow when it starts because,

  • The application might be waiting to import files.

  • A large number of methods might have to be compiled.

  • There might be a problem in code optimization (especially on single-CPU machines).

  • The problem might be caused by the Java application and not the JVM.

  • You recently migrated from a third-party development JVM to the JRockit JVM as the production JVM.

    The JRockit JVM is a just-in-time (JIT) compiling JVM designed for long-running applications. It compiles methods into machine code when the methods are called for the first time. So the application is relatively slow at startup because numerous new methods are compiled. However, after the application starts, it runs fast. Moreover, as the application runs, the JVM optimizes frequently called methods, improving the performance further.

2.2 Diagnosing Slow JVM Startup

  • Check whether the JVM compiles numerous methods at startup, by using the -Xverbose:codegen option. When you use this option, the following information about the methods being compiled is displayed:

    • Name of the method

    • Memory location

    • Duration of the compilation process

    • The total amount of time spent in compiling code since the application started.

    The following is an example of the output of the -Xverbose:codegen option.

    [INFO ][codegen][00004] #23 (Normal) java/lang/Object.registerNatives()V
    [INFO ][codegen][00004] #23 0.113-0.114 0x0000000100011B60-0x0000000100011C6B
       0.80 ms 128KB 0 bc/s (11.60 ms 63252 bc/s)
    [INFO ][codegen][00004] #24 (Normal)
       java/lang/OutOfMemoryError.<init>(Ljava/lang/String;)V
    [INFO ][codegen][00004] #24 0.115-0.115 0x0000000100011C80-0x0000000100011C92 0.38
       ms 64KB 15662 bc/s (11.99 ms 61731 bc/s
    

    Note that after the JIT compilation is complete, the application runs faster than during startup, because when the methods are called subsequently, the JVM runs the precompiled code.

  • Check the time taken to optimize methods by using the -Xverbose:opt option.

2.3 Diagnosing Slow Application Startup

The startup could be slow when, for example, the application is searching for a data file, looking up data in a database, and so on.

If you suspect that the application is causing the slow startup, use the Flight Recorder tool to record and analyze the application data.

For information about the Flight Recorder tool, see the Oracle JRockit Flight Recorder Run Time Guide.

2.4 Measuring Timing

You can measure the timing inside the application by inserting the System.nanoTime() and System.currentTimeMillis() methods. Note that these methods consume additional resources at run time, but the performance impact should be minimal.

System.nanoTime()

This method returns a monotonic timer value by using the most precise available system timer. The returned value is in nanoseconds, however the factual resolution of the timer can vary depending on the operating system and the hardware. Note that there is no conventional zero point to which you can relate the timer value. So you must measure the time at least twice to get any meaningful data.

nanoTime() uses different methods on different operating systems:

  • Windows: QueryPerformanceCounter()

  • Solaris: gethrtime()

  • Linux: clock_gettime() in librt if available; else gettimeofday()

To get information about timer resolution (and, on Linux, the method used to get a time value), start the JRockit JVM with the -Xverbose:timing command-line option.

The following is an example of a verbose timing report on Windows:

[INFO ][timing ] Fast time frequency is 1995000000hz
[INFO ][timing ] Drift is 0.00000021 = per day 0.018secs (max 300.000)
[INFO ][timing ] Hardware fast time enabled
[INFO ][timing ] Counter timer using resolution of 1995MHz

System.currentTimeMillis()

This method returns the current time in milliseconds. The current time is defined as the time since 00:00:00 UTC, January 1, 1970.

Milliseconds and Nanotime at Application Startup

To get the values of System.currentTimeMillis() and System.nanoTime() at the time the JVM started, use the -Xverbose:starttime command-line option.

The following is an example of the output for the -Xverbose:starttime command-line option:

INFO ][startti] VM start time: 1260962573921 millis 6922526 nanos 18442244770397334 ticks

The millis value is the same value that the System.currentTimeMillis() method would provide and the nanos value is the value that the System.nanoTime() method would provide.

2.5 Recommended Solutions for Slow JVM Startup

Tune for Faster Startup

Sometimes, the problem may be with how the JVM is tuned using command-line options.

For tips on how to tune the JVM for a faster startup, see the Oracle JRockit Performance Tuning Guide.

Eliminate Optimization Problems

At times, optimization could be the cause of the slow JVM startup, especially on single-CPU machines. For more information, see Section 5.2, "Troubleshoot Optimization Problems."

Eliminate Application Problems

If you determine that the slow start is due to problems in the Java application, investigate the cause of the problem from the application viewpoint. The problem is probably caused by methods that are subject to unnecessary synchronization or an insufficient number of synchronized resources. Try to locate the methods that are causing the bottleneck and, if possible, modify the code of your Java application.

Note that you can use the Flight Recorder tool to analyze synchronization problems. For more information, see the Oracle JRockit Flight Recorder Run Time Guide.

Contact Oracle Support

If the tuning solutions suggested in the Oracle JRockit Performance Tuning Guide do not help you solve the problem, contact Oracle Support as described in Chapter 9, "Contacting Oracle for Support"