Before we start with JVM tuning, we should note that there are various vendors available in the market for JVM. Based on the application requirement, we should select the JDK from the vendor.
Tomcat 7 comes with a heap size of 256 MB. Applications today need a large memory to run. In order to run the application, we have to tune the JVM parameter for Tomcat 7. Let's quickly discuss the default JVM configurations for Tomcat. The following steps describe the method to find out the Tomcat Process ID (PID) and memory values as shown in the next screenshot:
Run the following command on the terminal in Linux:
ps -ef |grep java
This will return all the Java processes running in the system, with all information such as the PID, where Tomcat is running, and so on:
root 4306 1 0 14:09 pts/1 00:00:04 /opt/jdk1.6.0_24/bin/java -Djava.util.logging.config.file=/opt/apache- tomcat-7.0.12/conf/logging.properties - Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager - Djava.endorsed.dirs=/opt/apache-tomcat-7.0.12/endorsed -classpath /opt/apache-tomcat-7.0.12/bin/bootstrap.jar:/opt/apache-tomcat- 7.0.12/bin/tomcat-juli.jar -Dcatalina.base=/opt/apache-tomcat-7.0.12 - Dcatalina.home=/opt/apache-tomcat-7.0.12 -Djava.io.tmpdir=/opt/apache- tomcat-7.0.12/temp org.apache.catalina.startup.Bootstrap start
In the previous output, 4306
is the PID for the Tomcat process. Now, we know the process ID for Tomcat, let's find out the memory allocated to the Tomcat instance using the command jmap
.
For checking the process ID for Tomcat on Windows, you have to run the following command:
tasklist |find "tomcat"
The following screenshot shows the output of the previous command, where 2112
is the process ID for the Tomcat process:
JMAP prints the complete picture for the shared Java Virtual Memory. It is a very good utility for the administrators to check the status of the shared memory. This command provides different options for executing the command. The following table describes the useful options of JMAP:
Options |
Description |
---|---|
|
Dumps the Java heap in |
|
Prints information on objects awaiting finalization |
|
Prints a heap summary |
|
Prints a histogram of the heap |
|
Prints class loader-wise statistics of permanent generation of the Java heap |
For more information on the JMAP command, please visit http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html.
The syntax for using the jmap command is ./jmap -heap <process id>
where<process id>
is the Java process for which we want to check the memory.
In the previous syntax, the -heap
option prints a heap summary, the GC algorithm used, the heap configuration, and the generation-wise heap usage.
If you want to run the jmap
command for a 64 bit VM, then use the command jmap -J-d64 -heap pid
.
In our current scenario, the PID is 4306:
[root@localhost bin]# ./jmap -heap 4306
The output of the previous command is as follows:
Attaching to process ID 4306, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 19.1-b02
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 268435456 (256.0MB)
NewSize = 1048576 (1.0MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 12582912 (12.0MB)
MaxPermSize = 67108864 (64.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 5111808 (4.875MB)
used = 3883008 (3.703125MB)
free = 1228800 (1.171875MB)
75.96153846153847% used
Eden Space:
capacity = 4587520 (4.375MB)
used = 3708360 (3.5365676879882812MB)
free = 879160 (0.8384323120117188MB)
80.83583286830357% used
From Space:
capacity = 524288 (0.5MB)
used = 174648 (0.16655731201171875MB)
free = 349640 (0.33344268798828125MB)
33.31146240234375% used
To Space:
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
tenured generation:
capacity = 11206656 (10.6875MB)
used = 3280712 (3.1287307739257812MB)
free = 7925944 (7.558769226074219MB)
29.274673908077485% used
Perm Generation:
capacity = 12582912 (12.0MB)
used = 6639016 (6.331459045410156MB)
free = 5943896 (5.668540954589844MB)
52.762158711751304% used
The previous command returns the following details:
If you see the previous heap allocation, then you can clearly differentiate the memory allocated to Tomcat 7. It is 256 MB, with 12 MB of Perm Generation.
To increase the heap size for Tomcat 7, we need to add the JAVA_OPTS
parameter in catalina.sh
, which can be found in TOMCAT_HOME/bin
.
Let us take an example of increasing the max heap size to 512 MB instead 256 MB. Also setting the Perm Gen = 256 MB
.
JAVA_OPTS="-Xms128m -Xmx512m -XX:MaxPermSize=256m"
Every change in configuration for the JVM parameter will be in effect after restarting the Tomcat server. You can verify the change done in the JVM parameter by running the jmap
command.
[root@localhost bin]# jmap -heap 21091
The output of the previous command is as follows:
Attaching to process ID 21091, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 19.1-b02
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 536870912 (512.0MB)
NewSize = 1048576 (1.0MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 12582912 (12.0MB)
MaxPermSize = 268435456 (256.0MB)
The highlighted line of code in the previous code snippet is reflecting the value changed after the recycle in the JVM parameter.
We can also define JRE_HOME, JAVA_OPTS, JAVA_ENDORSED_DIRS, JPDA_TRANSPORT, JPDA_ADDRESS, JPDA_SUSPEND, JPDA_OPTS, LOGGING_CONFIG, LOGGING_MANAGER
parameters in catalina.sh
.
After doing the real-time implementation of increasing the memory, we will understand the need to tune JVM and how the heap value increases and decreases in Tomcat 7. Another term which people often talk about is Garbage Collection (GC). JVM tuning is not complete without garbage collection.
Garbage means waste, but let's find out how this waste term fits in JVM.
Garbage is nothing but an object that resides in the JVM memory and is not currently used by any program.
Garbage collector is an algorithm which runs periodically, collects the status of active and inactive objects in the memory, and deletes the inactive objects to release memory.
Following are the facts for garbage collection:
When the GC algorithm is called, it collects all the inactive objects present in the memory and, hence, cleans the memory. It can be explained as the opposite of manual memory management:
It removes all inactive objects from the memory and all active threads will remain in the memory. The previous figure shows the state of the memory before and after the GC. There are mainly three types of GC collectors used in the real-time environment:
The following table describes the features of the serial collector:
Features |
Serial collector |
---|---|
Process |
Single thread is used for GC |
GC pause |
High |
Threading |
Single threaded |
Application |
Small application (data less than 100 MB) |
Advantage |
There is single thread communication |
The following table describes the features of the parallel collector:
Features |
Parallel collector |
---|---|
Process |
Parallel thread does minor GC |
GC pause |
Less than Serial |
Threading |
Multithreaded |
Application |
Mid-large |
Advantage |
Used in applications when peak performance is needed |
The following table describes the features of the concurrent collector:
Features |
Concurrent collector |
---|---|
Process |
GC is done concurrently |
GC pause |
Short pause |
Threading |
Multithreaded |
Application |
Mid-large |
Advantage |
Used in applications when a response is needed |
The Java HotSpot VM options are classified in two categories; standard and non-standard options.
Standard options are acknowledged by the Java HotSpot VM mentioned in the Java application launcher page for each OS. The following screenshot shows the standard option for the Java application launcher reference page:
Non-standard options are defined with -X
or -XX
options in the JVM. These options are grouped into three categories:
Options that begin with -X
are non-standard (not guaranteed to be supported on all VM implementations). Options that are specified with -XX
are not stable and are not recommended for casual use.
The following table describes very commonly used options for JVM:
Options |
Parameter |
Description |
---|---|---|
Behavioral Options |
|
Do young generation GC prior to a full GC |
Behavioral Options |
|
Use parallel garbage collection for scavenges |
Performance Options |
|
Maximum size of new generation (in bytes) |
Performance Options |
|
Size of the Permanent Generation (after exceeding |
Performance Options |
|
Minimum heap memory for the startup of Tomcat |
Performance Options |
|
Maximum memory allocated to the instance |
Performance Options |
|
Stack size for the heap |
Debugging Options |
|
Prints time spent in the JIT Compiler |
Debugging Options |
|
If an error occurs, save the error data to this file |
Debugging Options |
|
Path to the directory or filename for the heap dump |
Debugging Options |
|
Dump the heap to the file when |
Options |
Parameter |
Description |
Debugging Options |
|
Run user-defined commands on fatal error |
Debugging Options |
|
Run user-defined commands when an OutOfMemoryError is first thrown |
Debugging Options |
|
Print a histogram of class instances on Ctrl-Break |
For more information on the JVM non-standard options, please visit the link http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html.
GC prints the output of the garbage collection to the stdout
stream. At every garbage collection, the following five fields are printed:
[%T %B->%A(%C), %D]
%T:
This is "GC" when the garbage collection is a scavenge, and "Full GC:" is performed, then scavenge collects live objects from the new generation only, whereas a full garbage collection collects objects from all spaces in the Java heap.%B:
It is the size of the Java heap used before the garbage collection, in KB.%A:
It is the size of the Java heap after the garbage collection, in KB.%C:
It is the current capacity of the entire Java heap, in KB.%D:
It is the duration of the collection in seconds.3.145.69.255