Five JVM command line flags that Java programmers must know

  • 2020-04-01 03:43:42
  • OfStack

This article was written exclusively for developerworks by Ted Neward, President of Neward & Associates. "you don't know 5..." As part of this series, the JVM is the heavy-duty machine behind the Java functionality and performance that most developers take for granted. However, few of us understand how the JVM works -- things like task allocation and garbage collection, spinning threads, opening and closing files, breaking and/or JIT compiling Java bytecode, and so on.

Not only will unfamiliarity with the JVM affect application performance, but when the JVM goes wrong, it can be difficult to try to fix.

This article covers command-line flags that you can use to diagnose and tune the performance of your Java virtual machine.

1. DisableExplicitGC
I can't remember how many times I've been asked to consult on application performance issues, but simply running grep quickly across the code reveals the problem shown in listing 1 -- the original Java performance antipattern:

Listing 1. System. The gc ();


// We just released a bunch of objects, so tell the stupid 
// garbage collector to collect them already! 
System.gc();

Explicit garbage collection is a very bad idea -- like locking you in a phone booth with a crazy bulldog. Although the syntax of the invocation is implementation-dependent, if your JVM is running a generational garbage collector (mostly) system.gc (); Force the VM to perform a "clean all" of the heap, although some are not necessary. Sweeping it all up is orders of magnitude more expensive than a regular GC operation, which is a simple math problem.

You can ignore me -- Sun's engineers provided a JVM flag for this particular human error; The -xx :+DisableExplicitGC flag automatically converts the system.gc () call to an empty operation, giving you the opportunity to run your code and see for yourself whether system.gc () is harmful or beneficial to overall JVM execution.

2. HeapDumpOnOutOfMemoryError

Have you ever been in a situation where the JVM was not working, constantly throwing outofmemoryerrors, and you couldn't create a debugger for yourself to catch it or see what was wrong? Occasional and/or indeterminate problems like these often drive developers crazy.

emptor

Not all VMS support all command-line flags, with the exception of Sun/Oracle VMS. The best way to find out if a flag is supported is to try it out and see if it works. If these flags are not technically supported, you take full responsibility for using them. I, Sun/Oracle, and IBM would be irresponsible if any of these flags made your code, your data, your server, or everything about you disappear without a trace. As a precaution, it is recommended to experiment in a virtual (non-production) environment first.

At this time is what you want, the JVM die as captured heap a snapshot - - XX: just + HeapDumpOnOutOfMemoryError command to complete this operation.

Running this command tells the JVM to take a "heap dump snapshot" and save it in a file for processing, usually using the jhat utility (which I covered in the last article). You can specify the actual path to the saved file using the corresponding -xx :HeapDumpPath flag. (regardless of where the file is saved, be sure that the file system and/or Java processes must have permission configurations to write to.)

3. The bootclasspath

It is helpful to periodically put a class into the classpath, which is slightly different from the classpath that comes with the stock JRE or that is somehow extended. The new Java Crypto API provider is an example. If you want to extend the JRE, your custom implementation must be available using a bootstrap ClassLoader that loads java.lang.object and all its associated files in rt.jar.

Although you can illegally open rt.jar and move your custom implementation or new packets into it, you are technically violating the protocol you agreed to when you downloaded the JDK.

Instead, use the JVM's own -xbootclasspath option, as well as skin-xbootclasspath /p and -xbootclasspath /a.

-xbootclasspath allows you to set up the full bootclasspath (which typically includes a reference to rt.jar), as well as some other jar files shipped with the JDK (which are not part of rt.jar). -xbootclasspath /p puts the value in front of the existing bootclasspath and append -xbootclasspath /a to it.

For example, if you changed the java.lang.integer in the library and placed the change under a subpath mods, the -xbootclasspath /amods parameter puts the new Integer in front of the default parameter.

4. The verbose

Verbose is a useful first-level diagnostic user for virtual or any type of Java application. The flag has three child flags: gc, class, and jni.

When developers try to find out if the JVM garbage collector is failing or causing poor performance, the first thing they usually do is perform the gc. Unfortunately, interpreting gc output is a hassle -- enough to write a book on. Worse, the output printed on the command line can change in different Java versions or not in different JVMS, making it harder to interpret correctly.

In general, if the garbage collector is a generational collector (as most "enterprise-class" VMs are). Some sort of virtual flag will appear to indicate an all-clean GC path; In the Sun JVM, the flag begins at the beginning of the GC output line with "[FullGC...] "Form appears.

To diagnose class conflicts between classloaders and/or mismatches, class can be a great help. It reports not only when the class is loaded, but also where the class is loaded from, including the path to the JAR (if from the JAR).

Jni is rarely used, except when using jni or local libraries. When turned on, it reports various JNI events, such as when the local library is loaded and when the method bounces back. Again, the output varies between JVM versions.

5. com mand - line - X

I've listed some of my favorite command-line options available in the JVM, but there are a few more that you need to discover for yourself, run the command-line argument -x, and list all the non-standard (but mostly safe) arguments that the JVM provides -- for example:

-xint, running the JVM in interpreted mode (useful for testing whether the JIT compiler actually works on your code or verifying that there is a bug in the JIT compiler).

-xloggc:, does the same thing as -verbose:gc, but logs a file without printing it to a command line window.

JVM command-line options change frequently, so it's a good idea to review them periodically. Even staring at your monitor late at night is not the same as coming home at 5pm for dinner with your wife and kids (or killing your enemies in Mass Effect 2, depending on your preference).

conclusion

In a production environment, the command line flag is not designed for permanent use -- in fact, there is no non-standard command line flag that is dedicated to production use, except for the flag that you terminate to tune the JVM garbage collector. However, it is useful as a tool for probing the inner workings of virtual machines that are otherwise completely opaque.


Related articles: