To deploy Java web applications within Web Server 7.0, you need to perform the following tuning within your server:
Tuning web application configuration settings, see Web Server Tuning and the values in default-web.xml like reload interval.
This section describes how to improve performance of web applications, through deployment and configuration settings.
Deployment settings can have significant impact on performance. Follow these guidelines when configuring deployment settings for best performance:
Use Pre-compiled JavaServer Pages
Disable Dynamic Application Reloading
Compiling JSP files is resource intensive and time consuming. Precompiling JSP files before deploying applications on the server will improve application performance. When you compile in advance, only the resulting servlet class files will be deployed.
You can specify on the server to pre-compile JSP files when you deploy an application through the Admin Console, through CLI or GUI. You can also specify on the server to pre-compile JSP files for an already deployed application with the Admin Console.
If dynamic reloading is enabled, the server periodically checks for changes in deployed applications and automatically reloads the application with the changes. Dynamic reloading is intended for development environments and is also incompatible with session persistence. To improve performance, disable dynamic class reloading.
Remove .reload from the web application directory.
On a production system, improve web container performance by disabling dynamic JSP reloading. To do so, edit the default-web.xml file in the config directory for each instance. Change the servlet definition for a JSP file to look like this:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>httpMethods</param-name> <param-value>GET, HEAD, POST</param-value> </init-param> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>mappedfile</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>developments</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>genStrAsCharArray</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>trimSpaces</param-name> <param-value>true</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet>
The suggested manual changes requires you to run either pull-config through the CLI or the Admin Console.
The Server produces writes log messages and exception stack trace output to the log file in the logs directory of the instance, Naturally, the volume of log activity can impact server performance; particularly in benchmarking situations.
The efficiency of any application depends on how well memory and garbage collection are managed. The following sections provide information on optimizing memory and allocation functions:
Tracing Garbage Collection
Other Garbage Collector Settings
Tuning the Java Heap
Re-basing DLLs on Windows
Monitoring the Garbage Collection (GC) activity at the development server and accordingly tuning JVM and GC settings before deploying the server into production is necessary. The GC settings vary depending on the application you are running.
Garbage collection reclaims the heap space previously allocated to objects no longer needed. The process of locating and removing the dead objects can stall any application and consume as much as 25 percent throughput.
Almost all Java Runtime Environments come with a generational object memory system and sophisticated GC algorithms. A generational memory system divides the heap into a few carefully sized partitions called generations. The efficiency of a generational memory system is based on the observation that most of the objects are short lived. As these objects accumulate, a low memory condition occurs forcing GC to take place.
The heap space is divided into old and the new generations. The new generation includes the new object space (eden), and two survivor spaces. The JVM allocates new objects in the eden space, and moves longer lived objects from the new generation to the old generation. Keep the heap size low, so that customers can increase the heap size depending on their needs. To increase the heap size, refer to the link, http://www.devx.com/tips/Tip/5578
The young generation uses a fast copying garbage collector which employs two semi-spaces (survivor spaces) in the eden, copying surviving objects from one survivor space to the second. Objects that survive multiple young space collections are tenured, meaning they are copied to the tenured generation. The tenured generation is larger and fills up less quickly. Garbage is collected less frequently; and each collection takes longer than a young space only collection. Collecting the tenured space is also referred to as doing a full generation collection.
The frequent young space collections are quick, lasting only a few milliseconds, while the full generation collection takes a longer, tens of milliseconds to a few seconds, depending upon the heap size. Other GC algorithms, such as the Concurrent Mark Sweep (CMS) algorithm, are incremental. They divide the full GC into several incremental pieces. This provides a high probability of small pauses. This process comes with an overhead and is not required for enterprise web applications.
When the new generation fills up, it triggers a minor collection in which the surviving objects are moved to the old generation. When the old generation fills up, it triggers a major collection which involves the entire object heap.
Both HotSpot and Solaris JDK use thread local object allocation pools for lock-free, fast, and scalable object allocation. So custom object pooling is not often required. Consider pooling only if object construction cost is high and significantly affects execution profiles.
The -Xms and -Xmx parameters define the minimum and maximum heap size. As collections occur when generations fill up, throughput is inversely proportional to the available memory. By default, JVM grows or shrinks the heap at each collection. This helps maintain the proportion of free space to living object at each collection within a specific range. The range is set as a percentage by the parameters -XX:MinHeapFreeRatio=<minimum> and -XX:MaxHeapFreeRatio=<maximum>; and the total size is bound by -Xms and -Xmx.
JVM heap setting for Web Server should be based on the available memory on the system and frequency and duration of garbage collection. You can use -verbose:gc jvm option or the J2SE 5.0 monitoring tools to determine the frequency of garbage collection. For more information on J2SE 5.0 monitoring tools, see J2SE 5.0 Monitoring Tools. The maximum heap size should be determined based on the process data model (32-bit or 64-bit) and availability of virtual and physical memory on the system. Excessive use of physical memory for Java heap may cause paging of virtual memory to disk during garbage collection, resulting in poor performance. For more information on Java tuning, see http://java.sun.com/performance/reference/whitepapers/tuning.html.
This section describes how to use different garbage collector within Web Server.
Use the CMS collector as the GC algorithm. This collector can cause a drop in throughput for heavily utilized systems, because it is running constantly, but it prevents the long pauses that can occur when the garbage collector runs infrequently.
Procedure to use the CMS collector:
Shut down the server.
Configure the CMS collector in the server instance.
add the following JVM options either using the Admin Console or by using the CLI:
Use the jvmstat utility to monitor HotSpot garbage collection.
The two primary measures of garbage collection performance are throughput and pauses. Throughput is the percentage of the total time spent on other activities apart from GC. Pauses are times when an application appears unresponsive due to GC.
Two other considerations are footprint and promptness. Footprint is the working size of the JVM process, measured in pages and cache lines. Promptness is the time between when an object becomes dead, and when the memory becomes available.
This is an important consideration for distributed systems. A particular generation size makes a trade-off between these four metrics. For example, a large young generation likely maximizes throughput, but at the cost of footprint and promptness.
J2SE 5.0 supports tools that can be used to provide information on performance and resource consumption for running applications. Two commonly used tools, jconsole and jstat, are discussed in this section.
For a complete list of available tools and their usage, see J2SE 5.0 Trouble-Shooting and Diagnostic Guide.
The JMX based graphical tool jconsole is used to display thread usage, memory consumption, and class loading details. For more information about this tool, see http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html.
To use the tool, you need to:
1. Set the JVM option -Dcom.sun.management.jmxremote in server.xml.
Use the Admin Console or CLI to set this JVM option. For more information, see Configuring Your JVM in Sun Java System Web Server 7.0 Update 7 Administrator’s Guide.
2. Start jconsole.
The binary is available in $JAVA_HOME/bin directory. Specify the pid in the command line when invoking the tool. The pid of the Web Server process is obtained either from the log file or by locating the child webservd process.
You may also invoke jconsole without the pid argument and then select the appropriate VM from the window displaying available VMs.
Thejstat utility can be used to tune the Java heap size and diagnose performance issues related to heap and garbage collection. This utility can be used without any server configuration changes as the VM instrumentation is enabled by default. For more information, see http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html.
Binary logging is a functionality introduced in Sun Java System Web Server 7.0 Update 5. This feature allows server information to be stored in a single log file that contains binary, unformatted log data of all the web sites hosted on a server. It thus minimizes the usage of system resources used for logging, may improve performance and scalability, and at the same time records detailed log information. The feature is enabled by making changes in the server.xml file. The server.xml should have a new element mode with binary value specified in access-log. If the mode element is missing or its value is not specified, the default value is text. The text option writes access log in ASCII format, as was in previous Web Server releases. However, if the mode element is specified with binary value, the access log is written in binary format.
To enable binary logging, add the following in the server.xml:
<access-log> <file>../logs/access/<file> <mode>binary</mode> </access-log>
In Sun Java System Web Server 7.0 , the binary log file is bundled in the product bin directory called binlog and includes a log writer 1.0, log reader 1.0 and a version identifier. The version identifier identifies the versions of log writer and log reader and will be upgraded accordingly in future releases.
The log writer 1.0 writes the log format into a raw binary log file which is not human readable. The binary log reader 1.0 takes the binary access log file as input, extracts it and prints the log in human readable ASCII format on the console.
Binary log accepts the following arguments:
Displays the help.
Displays the version number of the binary log reader.
It is the input binary log file name. The default value is stdin.
Binary log is executed in the following two ways:
$binlog < access.log
$binlog -i access.log