Preface:

Current JVMS run Java programs (and other compatible languages) with remarkable efficiency and stability. Adaptive memory management, garbage collection, just-in-time compilation, dynamic class loading, lock optimization — these are just a few of the amazing things that happen in some scenarios, but they are almost never directly relevant to the average programmer. At runtime, the JVM continuously evaluates and optimizes the application or parts of the application.

With this level of automation (or so much of it), the JVM still provides plenty of tools for external monitoring and manual tuning. In the case of errors or low performance, the JVM must be able to be debugged by an expert. Incidentally, in addition to these magical features hidden in the engine, allowing a wide range of manual tuning is one of the advantages of modern JVMS. Interestingly, some command-line arguments can be passed into the JVM at startup. Some JVMS provide hundreds of these parameters, so it’s easy to get lost without this knowledge. The goal of this series of blogs is to highlight some of the everyday parameters and where they apply. We will focus on the Sun/Oracle HotSpot JVM for Java6, and in most cases these parameters will also apply to other popular JVMS.

-server and -client

There are two types of HotSpot JVMS, namely “server” and “client”. The default in the server VM provides a larger space for the heap and a parallel garbage collector, as well as a greater degree of code optimization at run time. Client VMS are more conservative, resulting in shorter JVM startup times and less memory footprint. There is a concept called “JVM ergonomics” that automatically selects the type of JVM at startup based on available hardware and operating systems. Specific criteria can be found here. From the standard table, we can see that the client VM is only available on 32-bit systems.

If we don’t like pre-selected JVMS, we can use the -server and -client parameters to set up the VM to use the server or client side. Although the server VM was originally intended to be a long-running server process, it now appears to perform better than the client VM when running standalone applications. When application performance is important, I recommend using the -server parameter to select the server VM. A common problem: on a 32-bit system, the HotSpot JDK can run the server VM, but the 32-bit JRE can only run the client VM.

-version and -showversion

How do we know which version of Java and JVM type we have installed when we invoke the “Java” command? Installing more than one Java on the same system runs the risk of running the wrong JVM if you are not careful. In terms of preinstalling JVMS on different Versions of Linux, I admit it’s getting a lot better than it used to. Fortunately, we can now use the -version parameter, which prints out information about the JVM in use. Such as:

$Java -version Java version "1.6.0_24" Java(TM) SE Runtime Environment (build 1.6.0_24-B07) Java HotSpot(TM) Client VM (build 19.1 - b02, mixed mode,Copy the code

– the version parameter terminates the JVM immediately after printing the above information. A similar argument, -showversion, can be used to output the same information, but -showversion will then process and execute the Java program. Therefore, -showversion is a useful complement to the command line of almost any Java application. You never know when you might suddenly need to know something about the JVM being used by a particular Java application when it crashes. By adding -showversion at startup, we can ensure that this information is available when we need it. The output shows the Java version number (1.6.0_24) and the exact BUILD number of the JRE (1.6.0_24-B07). We can also see the JVM name (HotSpot), type (Client), and build ID (19.1-b02). In addition, we also know that the JVM runs in mixed mode, which is HotSpot’s default mode, meaning that the JVM can dynamically compile bytecode into native code at runtime. We can also see that Class Data sharing is enabled, and class data sharing is a kind of read-only cache (in jSA files,” Java Shared Archive “), a system class that stores the JRE and is used as a Shared resource by all Java process classloaders. Class Data sharing may show performance benefits in cases where all Class data is often read from JAR documents.

Xint, – Xcomp, and – Xmixed

The -xint and -xcomp parameters are not very relevant to our daily work, but I’m interested in learning more about the JVM through them. In interpreted mode, the -xint tag forces the JVM to execute all the bytecode, which of course slows down the performance, usually by a factor of 10 or more. The -xcomp argument is the opposite of this (-xint), and the JVM compiles all the bytecode into native code the first time it is used, resulting in maximum optimization. This sounds good because it bypasses the slow interpreter entirely. However, many applications also suffer a performance penalty when using -xcomp, which is certainly less than when using -xint, because -xcomp does not enable the JVM to enable the full functionality of the JIT compiler. The JIT compiler creates method usage files at run time and then optimizes each method step by step, sometimes proactively optimizing the behavior of the application. These optimization techniques, such as Optimistic Branch prediction, cannot be used effectively without first analyzing the application. Methods, on the other hand, are compiled only if they prove relevant, that is, build some kind of hot spot in the application. Methods that are called infrequently (or even once) continue to execute in explain mode, reducing compilation and optimization costs.

Note that blending mode also has its own argument, -xmixed. The default mode for the latest version of HotSpot is mixed mode, so we don’t need to specify this tag. Let’s make a simple use case of populating a HashMap with objects and retrieving its results. In each case, the running time is the average of many runs.

$java-server-showVersion Benchmark Java version "1.6.0_24" Java(TM) SE Runtime Environment (build 1.6.0_24-B07) Java HotSpot(TM) Server VM (Build 19.1-B02, Mixed mode)Average Time: 0.856449 seconds $java-server-showversion -xcomp Benchmark Java version "1.6.0_24" Java(TM) SE Runtime Environment Java HotSpot(TM) Server VM (Build 19.1-B02, Compiled mode) Average Time: 0.950892 seconds $java-server-showversion-xint Benchmark Java version "1.6.0_24" Java(TM) SE Runtime Environment (Build 1.6.0_24-b07) Java HotSpot(TM) Server VM (Build 19.1-B02, Interpreted mode) Average time: 7.622285 secondsCopy the code

Of course, there are plenty of examples where -xcomp works well. Especially for long-running applications, I strongly recommend that you use the JVM’s default Settings and let the JIT compiler, which is one of the most important components of the JVM, realize its dynamic potential. In fact, it’s the JVM’s advances in this area that have made Java less slow.