- Java HotSpot™ Virtual Machine Performance Enhancements
- Tiered Compilation
- Compressed Oops
- Zero-Based Compressed Ordinary Object Pointers (oops)
- Escape Analysis
- NUMA Collector Enhancements
- NUMA Performance Metrics
- Java hotspot server vm windows
- Categories of Java HotSpot VM Options
- Some Useful -XX Options
- Java hotspot server vm windows
- Frequently Asked Questions About the Java HotSpot VM
- Frequently Asked Questions
- General
- Memory and Garbage Collection
- JIT Compiler
- 64-bit Java
Java HotSpot™ Virtual Machine Performance Enhancements
Tiered Compilation
Tiered compilation, introduced in Java SE 7, brings client startup speeds to the server VM. Normally, a server VM uses the interpreter to collect profiling information about methods that is fed into the compiler. In the tiered scheme, in addition to the interpreter, the client compiler is used to generate compiled versions of methods that collect profiling information about themselves. Since the compiled code is substantially faster than the interpreter, the program executes with greater performance during the profiling phase. In many cases, a startup that is even faster than with the client VM can be achieved because the final code produced by the server compiler may be already available during the early stages of application initialization. The tiered scheme can also achieve better peak performance than a regular server VM because the faster profiling phase allows a longer period of profiling, which may yield better optimization.
Both 32 and 64 bit modes are supported, as well as compressed oops (see the next section). Use the -XX:+TieredCompilation flag with the java command to enable tiered compilation.
Compressed Oops
An «oop», or ordinary object pointer in Java Hotspot parlance, is a managed pointer to an object. An oop is normally the same size as a native machine pointer, which means 64 bits on an LP64 system. On an ILP32 system, maximum heap size is somewhat less than 4 gigabytes, which is insufficient for many applications. On an LP64 system, the heap used by a given program might have to be around 1.5 times larger than when it is run on an ILP32 system. This requirement is due to the expanded size of managed pointers. Memory is inexpensive, but these days bandwidth and cache are in short supply, so significantly increasing the size of the heap and only getting just over the 4 gigabyte limit is undesirable.
Managed pointers in the Java heap point to objects which are aligned on 8-byte address boundaries. Compressed oops represent managed pointers (in many but not all places in the JVM software) as 32-bit object offsets from the 64-bit Java heap base address. Because they’re object offsets rather than byte offsets, they can be used to address up to four billion objects (not bytes), or a heap size of up to about 32 gigabytes. To use them, they must be scaled by a factor of 8 and added to the Java heap base address to find the object to which they refer. Object sizes using compressed oops are comparable to those in ILP32 mode.
The term decode is used to express the operation by which a 32-bit compressed oop is converted into a 64-bit native address into the managed heap. The inverse operation is referred to as encoding.
Compressed oops is supported and enabled by default in Java SE 6u23 and later. In Java SE 7, use of compressed oops is the default for 64-bit JVM processes when -Xmx isn’t specified and for values of -Xmx less than 32 gigabytes. For JDK 6 before the 6u23 release, use the -XX:+UseCompressedOops flag with the java command to enable the feature.
Zero-Based Compressed Ordinary Object Pointers (oops)
When using compressed oops in a 64-bit Java Virtual Machine process, the JVM software asks the operating system to reserve memory for the Java heap starting at virtual address zero. If the operating system supports such a request and can reserve memory for the Java heap at virtual address zero, then zero-based compressed oops are used.
Use of zero-based compressed oops means that a 64-bit pointer can be decoded from a 32-bit object offset without adding in the Java heap base address. For heap sizes less than 4 gigabytes, the JVM software can use a byte offset instead of an object offset and thus also avoid scaling the offset by 8. Encoding a 64-bit address into a 32-bit offset is correspondingly efficient.
For Java heap sizes up around 26 gigabytes, any of Solaris, Linux, and Windows operating systems will typically be able to allocate the Java heap at virtual address zero.
Escape Analysis
Escape analysis is a technique by which the Java Hotspot Server Compiler can analyze the scope of a new object’s uses and decide whether to allocate it on the Java heap.
Escape analysis is supported and enabled by default in Java SE 6u23 and later.
The Java Hotspot Server Compiler implements the flow-insensitive escape analysis algorithm described in:
Based on escape analysis, an object’s escape state might be one of the following:
- GlobalEscape – An object escapes the method and thread. For example, an object stored in a static field, or, stored in a field of an escaped object, or, returned as the result of the current method.
- ArgEscape – An object passed as an argument or referenced by an argument but does not globally escape during a call. This state is determined by analyzing the bytecode of called method.
- NoEscape – A scalar replaceable object, meaning its allocation could be removed from generated code.
After escape analysis, the server compiler eliminates scalar replaceable object allocations and associated locks from generated code. The server compiler also eliminates locks for all non-globally escaping objects. It does not replace a heap allocation with a stack allocation for non-globally escaping objects.
Some scenarios for escape analysis are described next.
The server compiler might eliminate certain object allocations. Consider the example where a method makes a defensive copy of an object and returns the copy to the caller.
The method makes a copy to prevent modification of the original object by the caller. If the compiler determines that the getPerson method is being invoked in a loop, it will inline that method. In addition, through escape analysis, if the compiler determines that the original object is never modified, it might optimize and eliminate the call to make a copy.
The server compiler might eliminate synchronization blocks (lock elision) if it determines that an object is thread local. For example, methods of classes such as StringBuffer and Vector are synchronized because they can be accessed by different threads. However, in most scenarios, they are used in a thread local manner. In cases where the usage is thread local, the compiler might optimize and remove the synchronization blocks.
NUMA Collector Enhancements
The Parallel Scavenger garbage collector has been extended to take advantage of machines with NUMA (Non Uniform Memory Access) architecture. Most modern computers are based on NUMA architecture, in which it takes a different amount of time to access different parts of memory. Typically, every processor in the system has a local memory that provides low access latency and high bandwidth, and remote memory that is considerably slower to access.
In the Java HotSpot Virtual Machine, the NUMA-aware allocator has been implemented to take advantage of such systems and provide automatic memory placement optimizations for Java applications. The allocator controls the eden space of the young generation of the heap, where most of the new objects are created. The allocator divides the space into regions each of which is placed in the memory of a specific node. The allocator relies on a hypothesis that a thread that allocates the object will be the most likely to use the object. To ensure the fastest access to the new object, the allocator places it in the region local to the allocating thread. The regions can be dynamically resized to reflect the allocation rate of the application threads running on different nodes. That makes it possible to increase performance even of single-threaded applications. In addition, «from» and «to» survivor spaces of the young generation, the old generation, and the permanent generation have page interleaving turned on for them. This ensures that all threads have equal access latencies to these spaces on average.
The NUMA-aware allocator is available on the Solaris™ operating system starting in Solaris 9 12/02 and on the Linux operating system starting in Linux kernel 2.6.19 and glibc 2.6.1.
The NUMA-aware allocator can be turned on with the -XX:+UseNUMA flag in conjunction with the selection of the Parallel Scavenger garbage collector. The Parallel Scavenger garbage collector is the default for a server-class machine. The Parallel Scavenger garbage collector can also be turned on explicitly by specifying the -XX:+UseParallelGC option.
The -XX:+UseNUMA flag was added in Java SE 6u2.
Note: There was a known bug in the Linux Kernel that may cause the JVM to crash when being run with -XX:UseNUMA . The bug was fixed in 2012, so this should not affect the latest versions of the Linux Kernel. To see if your Kernel has this bug, you can run the native reproducer.
NUMA Performance Metrics
When evaluated against the SPEC JBB 2005 benchmark on an 8-chip Opteron machine, NUMA-aware systems showed the following performance increases:
- 32 bit – About 30 percent increase in performance with NUMA-aware allocator
- 64 bit – About 40 percent increase in performance with NUMA-aware allocator
Java hotspot server vm windows
Your search did not match any results.
We suggest you try the following to help find what you’re looking for:
- Check the spelling of your keyword search.
- Use synonyms for the keyword you typed, for example, try “application” instead of “software.”
- Try one of the popular searches shown below.
- Start a new search.
Java HotSpot VM Options
Please note that this page only applies to JDK 7 and earlier releases. For JDK 8 please see the Windows, Solaris reference pages.
This document provides information on typical command-line options and environment variables that can affect the performance characteristics of the Java HotSpot Virtual Machine. Unless otherwise noted, all information in this document pertains to both the Java HotSpot Client VM and the Java HotSpot Server VM.
Categories of Java HotSpot VM Options
- Options that begin with -X are non-standard (not guaranteed to be supported on all VM implementations), and are subject to change without notice in subsequent releases of the JDK.
- Options that are specified with -XX are not stable and are subject to change without notice.
Users of JDKs older than 1.3.0 who wish to port to a Java HotSpot VM, should see Java HotSpot Equivalents of Exact VM flags.
Some Useful -XX Options
Default values are listed for Java SE 6 for Solaris Sparc with -server. Some options may vary per architecture/OS/JVM version. Platforms with a differing default value are listed in the description.
- Boolean options are turned on with -XX:+ and turned off with -XX:- .Disa
- Numeric options are set with -XX: = . Numbers can include ‘m’ or ‘M’ for megabytes, ‘k’ or ‘K’ for kilobytes, and ‘g’ or ‘G’ for gigabytes (for example, 32k is the same as 32768).
- String options are set with -XX: = , are usually used to specify a file, a path, or a list of commands
Flags marked as manageable are dynamically writeable through the JDK management interface (com.sun.management.HotSpotDiagnosticMXBean API) and also through JConsole. In Monitoring and Managing Java SE 6 Platform Applications, Figure 3 shows an example. The manageable flags can also be set through jinfo -flag. The options below are loosely grouped into categories.
- Behavioral options change the basic behavior of the VM.
- Garbage First (G1) Garbage Collection Options
- Performance tuning options are knobs which can be used to tune VM performance.
- Debugging options generally enable tracing, printing, or output of VM information.
Java hotspot server vm windows
Your search did not match any results.
We suggest you try the following to help find what you’re looking for:
- Check the spelling of your keyword search.
- Use synonyms for the keyword you typed, for example, try “application” instead of “software.”
- Try one of the popular searches shown below.
- Start a new search.
Frequently Asked Questions About the Java HotSpot VM
This FAQ answers common questions about Java HotSpot Technology and about performance in general. Unless otherwise noted, all information on this page applies to both the HotSpot Client VM and the HotSpot Server VM as of Java SE version 1.4.
Frequently Asked Questions
General
What command-line options does the Java HotSpot VM provide for performance tuning?
Are there any resources for troubleshooting HotSpot issues?
For more in-depth troubleshooting discussion beyond the scope of this FAQ, please see the Java Trouble-Shooting and Diagnostic Guide [PDF]
I can’t get profiling to work, what should I do?
First, make sure you are running with -agentlib:hprof and try -agentlib:hprof=help to see the different kinds of profiling available. If you are still having problems please see the Java Trouble-Shooting and Diagnostic Guide [PDF]
I keep running out of file descriptors, what should I do?
Certain applications will use a lot of file descriptors. The only thing that you can do is to set the number of file descriptors allowed on the system higher. The hard limit default is 1024 and the soft limit default is 64. To set this higher you need to modify /etc/system by adding the following 2 definitions:
set rlim_fd_max = 4096 set rlim_fd_cur = 4096
Memory and Garbage Collection
Pause times are unnecessarily long, what parameters can I use to tune this?
There are several things to try in this arena. First, give -Xincgc a try. This uses the incremental garbage collection algorithm, which attempts to collect a fraction of the heap instead of the entire thing at once. For most programs this results in shorter pauses, although throughput is usually worse.
Next, you might try decreasing the amount of heap used. A larger heap will cause garbage collection pauses to increase because there is more heap to scan. Try -Xmx32m. If your application requires more memory than you can adjust the size of the eden (young generation space) with -XX:NewSize=. and -XX:MaxNewSize=. (for 1.3/1.4) or -Xmn in 1.4 and later. For some applications a very large eden helps, for others it will increase the times of minor collections. For most programs, collecting eden is much faster than other generations because most objects die young. If you currently invoke with something like:
-Xms384m -Xmx384m -XX:NewSize=128m -XX:MaxNewSize=128m
which will dedicate 1/3rd of the memory to eden. For 1.3, MaxNewSize is set to 32mb on Sparc, 2.5mb on Intel based machines. NewRatio (the ratio between the young/old generations) has values of 2 on Sparc Server, 12 on client Intel, and 8 everywhere else, as you can quickly determine, this is superseded by MaxNewSize’s defaults (rendering NewRatio ineffective for even moderately sized heaps). In 1.4 and later, MaxNewSize has been effectively set to infinity, and NewRatio can be used instead to set the value of the new generation. Using the above as an example, you can do the following in 1.4 and later:
-Xms384m -Xmx384m -XX:NewRatio=2
If you are worried about the number of garbage collections, but less worried about pause times, then increasing the heap should cause the number of full garbage collections to decrease, this is especially true if you increase the size of the eden space as well.
Many systems have less efficient memory management than in HotSpot. To work around this, some programs keep an «object pool», saving previously allocated objects in some freelist-like data structure and reusing them instead of allocating new ones. But. Don’t use object pools! Using object pools will fool the collector into thinking objects are live when they really aren’t. This may have worked before exact garbage collection became popular, but this is just not a good idea for any modern Java Virtual Machines.
How do I profile heap usage?
Try using -Xaprof to get a profile of the allocations (objects and sizes) of your application.
You can also try -agentlib:hprof=heap=all (or other option, try -agentlib:hprof=help for a list)
The VM prints «OutOfMemoryError» and exits. Increasing max heap size doesn’t help. What’s going on?
The Java HotSpot VM cannot expand its heap size if memory is completely allocated and no swap space is available. This can occur, for example, when several applications are running simultaneously. When this happens, the VM will exit after printing a message similar to the following.
Exception java.lang.OutOfMemoryError: requested <size> bytes
For more information, see the evaluation section of bug 4697804.
Why can’t I get a larger heap with the 32-bit JVM?
The maximum theoretical heap limit for the 32-bit JVM is 4G. Due to various additional constraints such as available swap, kernel address space usage, memory fragmentation, and VM overhead, in practice the limit can be much lower. On most modern 32-bit Windows systems the maximum heap size will range from 1.4G to 1.6G. On 32-bit Solaris kernels the address space is limited to 2G. On 64-bit operating systems running the 32-bit VM, the max heap size can be higher, approaching 4G on many Solaris systems.
As of Java SE 6, the Windows /3GB boot.ini feature is not supported.
If your application requires a very large heap you should use a 64-bit VM on a version of the operating system that supports 64-bit applications. See Java SE Supported System Configurations for details.
Should I pool objects to help GC? Should I call System.gc() periodically?
The answer is No!
Pooling objects will cause them to live longer than necessary. The garbage collection methods will be much more efficient if you let it do the memory management. We strongly advise taking out object pools.
Don’t call System.gc(), HotSpot will make the determination of when its appropriate and will generally do a much better job. If you are having problems with the pause times for garbage collection or it taking too long, then see the pause time question above.
What determines when softly referenced objects are flushed?
Starting with 1.3.1, softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap. This value can be adjusted using the -XX:SoftRefLRUPolicyMSPerMB flag, which accepts integer values representing milliseconds. For example, to change the value from one second to 2.5 seconds, use this flag:
The Java HotSpot Server VM uses the maximum possible heap size (as set with the -Xmx option) to calculate free space remaining.
The Java Hotspot Client VM uses the current heap size to calculate the free space.
This means that the general tendency is for the Server VM to grow the heap rather than flush soft references, and -Xmx therefore has a significant effect on when soft references are garbage collected.
On the other hand, the Client VM will have a greater tendency to flush soft references rather than grow the heap.
The behavior described above is true for 1.3.1 through Java SE 6 versions of the Java HotSpot VMs. This behavior is not part of the VM specification, however, and is subject to change in future releases. Likewise the -XX:SoftRefLRUPolicyMSPerMB flag is not guaranteed to be present in any given release.
Prior to version 1.3.1, the Java HotSpot VMs cleared soft references whenever it found them.
I’m getting lots of full GC’s when I turn on -verbose:gc at regular intervals, I’ve tuned the heap and it makes no difference, what’s going on?
If you’re using RMI, then you could be running into distributed GC. Also, some applications are adding explicit GC’s thinking that it will make their application faster. Luckily, you can disable this with a command line option in 1.3 and later. Try -XX:+DisableExplicitGC along with -verbose:gc and see if this helps.
JIT Compiler
What’s the difference between the -client and -server systems?
These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy.
Where do I get the server and client systems?
Client and server systems are both downloaded with the 32-bit Solaris and Linux downloads. For 32-bit Windows, if you download the JRE, you get only the client, you’ll need to download the SDK to get both systems.
For 64-bit, only the server system is included. On Solaris, the 64-bit JRE is an overlay on top of the 32-bit distribution. However, on Linux and Windows, it’s a completely separate distribution.
I would like java to default to -server. I have a lot of scripts which I cannot change (or do not want to change). Is there any way to do this?
Since Java SE 5.0, with the exception of 32-bit Windows, the server VM will automatically be selected on server-class machines. The definition of a server-class machine may change from release to release, so please check the appropriate ergonomics document for the definition for your release. For 5.0, it’s Ergonomics in the 5.0 Java[tm] Virtual Machine.
Should I warm up my loops first so that Hotspot will compile them?
Warming up loops for HotSpot is not necessary. HotSpot contains On Stack Replacement technology which will compile a running (interpreted) method and replace it while it is still running in a loop. No need to waste your applications time warming up seemingly infinite (or very long running) loops in order to get better application performance.
64-bit Java
What is 64-bit Java?
What it is: A 64-bit version of Java has been available to Solaris SPARC users since the 1.4.0 release of J2SE. A 64-bit capable J2SE is an implementation of the Java SDK (and the JRE along with it) that runs in the 64-bit environment of a 64-bit OS on a 64-bit processor. You can think of this environment as being just another platform to which we’ve ported the SDK. The primary advantage of running Java in a 64-bit environment is the larger address space. This allows for a much larger Java heap size and an increased maximum number of Java Threads, which is needed for certain kinds of large or long-running applications. The primary complication in doing such a port is that the sizes of some native data types are changed. Not surprisingly the size of pointers is increased to 64 bits. On Solaris and most Unix platforms, the size of the C language long is also increased to 64 bits. Any native code in the 32-bit SDK implementation that relied on the old sizes of these data types is likely to require updating.
Within the parts of the SDK written in Java things are simpler, since Java specifies the sizes of its primitive data types precisely. However even some Java code needs updating, such as when a Java int is used to store a value passed to it from a part of the implementation written in C.
What it is NOT: Many Java users and developers assume that a 64-bit implementation means that many of the built-in Java types are doubled in size from 32 to 64. This is not true. We did not increase the size of Java integers from 32 to 64 and since Java longs were already 64 bits wide, they didn’t need updating. Array indexes, which are defined in the Java Virtual Machine Specification, are not widened from 32 to 64. We were extremely careful during the creation of the first 64-bit Java port to insure Java binary and API compatibility so all existing 100% pure Java programs would continue running just as they do under a 32-bit VM.
Which platforms and Java releases support 64-bit operation?
In order to run a 64-bit version of Java you must have a processor and operating system that can support the execution of 64-bit applications. The tables below list the supported 64-bit operating systems and CPUs for J2SE 1.4.2 and Java SE 5.0.