JIT compilation is an important factor in optimizing performance. Because compilation is
carried out at run time, it is complicated to estimate the size of the program or the number of
compilations that are carried out. The JIT compiler has a cap on how much memory it can
allocate at run time to store compiled code and for most of applications the default cap is
more than sufficient.
However, certain programs, especially those programs that take advantage of certain
language features, such as reflection, can produce a number of compilations and use up the
allowed amount of code cache. After the limit of code cache is consumed, no more
compilations are performed. This situation can have a negative impact on performance if the
program begins to call many interpreted methods that cannot be compiled as a result. The
-Xjit:codetotal=<nnn> (where nnn is a number in KB units) option can be used to specify
the cap of the JIT code cache. The default is 64 MB or 128 MB for 32-bit and 64-bit JVMs.
Another consideration is how the code caches are allocated. If they are allocated far apart
from each other (more than 32 MB away), calls from one code cache to another carry higher
processing impact. The -Xcodecache<size> option can be used to specify how large each
allocation of code cache is. For example, -Xcodecache4m means 4 MB is allocated as code
cache each time the JIT compiler needs a new one, until the cap is reached. Typically, there
are multiple pieces (for example, 4) of code cache available at boot-up time to support
multiple compilation threads. It is important to alter the default code cache size only if it is
insufficient, as a large but empty code cache needlessly consumes resources.
Two techniques can be used to determine if the code cache allocation sizes or total limit must
be altered. First, a Java core file can be produced by running kill -3 <pid> at the end/stable
state of your application. The core file shows how many pieces of code cache are allocated.
The active amount of code cache can be estimated by summing up all of the pieces.
For example, if 20 MB is needed to run the application, -Xcodecache5m (four pieces of 5 MB
each) typically allocates 20 MB code caches at boot-up time, and they are likely close to each
other and have better performance for cross-code cache calls. Second, to determine if the
total code cache is sufficient, the -Xjit:verbose option can be used to print method names
as they are compiled. If compilation fails because the limit of code cache is reached, an error
to that effect is printed.
For more information, see http://www.redbooks.ibm.com/abstracts/sg248079.html?Open