25.6. Tuning JBoss Enterprise Web Platform

Before tuning the JBoss Enterprise Web Platform, please ensure that you are familiar with its components, as outlined in the introduction section of this book. You should also be familiar with any particular services your application may use on the server and tune them to improve performance. It is also important to establish optimal database connections used by your applications and set these on the server. This section discusses these among other JBoss Enterprise Web Platform performance tuning topics.

25.6.1. Memory usage

Memory usage of Java applications including the JBoss Enterprise Web Platform is dictated by the heap space allocated. You could, for example, reduce the currently allocated 1 gigabyte heap space to 800 megabytes to reduce memory footprint (if you have enough headroom).
The Java Virtual Machine (JVM) manages segments generations of memory. If a segment of the heap space is exhausted, you will see a Java OutOfMemoryError (OOME). The application should be restarted to correct any bad state. If the available memory is insufficient, increase the maximum Java memory size. You may need to switch to a 64-bit JVM.
An OOME is also thrown when the permanent memory is exhausted. Permanent memory is not part of the heap. It is a JVM-specific area of memory where information about loaded classes is maintained. If you have a large number of classes, this area may not be sufficient and your applications will fail to deploy or redeploy. The default value for the -server switch is 64 megabytes. You can increase permanent memory space to avoid OOMEs like so:
-XX:MaxPermSize=256m
This adds 256 megabytes of permanent space to the 512 megabytes originally provided by the heap for a total of 768 megabytes. Remember that the JVM consumes system memory, and that stack space is also consumed on a per-thread basis (size varies with operating system).
The total memory allocated from the system in the following is 768 megabytes:
-XX:MaxPermSize=256m -Xmx512m
This is not the total size of the VM and does not include the space the VM allocates for the C heap or stack space.

HotSpot JVM

The HotSpot JVM consists of various garbage collection tools which you can use to collect garbage collection information that you can use to tune your applications. You can find more information on the HotSpot Virtual machine on http://java.sun.com/javase/technologies/hotspot/.

Monitoring Tools for Java 6

Java 6 includes new tools that help monitor Java applications. Jmap can generate a heap dump file (http://java.sun.com/javase/6/docs/technotes/tools/share/jmap.html) that can easily be read by the Eclipse Memory Analyzer tool (http://www.eclipse.org/mat/). The jstat tool (http://java.sun.com/javase/6/docs/technotes/tools/share/jstat.html) can help give you a precise picture of your permanent memory space and the other segments on the Java memory heap.

25.6.1.1. VFS Tuning

Most tuning options for the Virtual File System (VFS) can be found in the VFSUtils class. Its string constants point us to different possible system property settings we can use to configure VFS behavior:
jboss.vfs.forceCopy
Defines how nested JARs are handled. If true (the default), a temporary copy of the nested JAR is created and the VFS is re-wired accordingly. If false, nested JARs are handled in-memory. No temporary copy is created, but this option consumes more memory.
jboss.vfs.forceNoReaper
Set to false by default. This specifies that JAR files are closed asynchronously by a separate reaper thread, which can improve performance. To close JAR files synchronously, force no usage of the reaper thread by setting this to true. This can also be defined using the URI query and the noReaper query section.
jboss.vfs.forceCaseSensitive
When true, forces differentiation between lower and upper case file paths. The default value is false.
jboss.vfs.optimizeForMemory
When true, re-orders in-memory JAR handling to reduce memory consumption. The default value is false.
jboss.vfs.cache
Define this class (org.jboss.virtual.spi.cache.helpers.NoopVFSCache) to reuse existing temporary files so that unpacking and wiring does not to be repeated. The VFS registry uses this class definition to keep its existing VFS roots. Every VirtualFile lookup from the VFS class uses this singleton cache instance to check for an existing matching cache entry. Matching also considers any existing ancestor that lets you use the same VirtualFile instance.
25.6.1.1.1. VFS Cache Tuning
The VFS cache holds VFS roots, from which any VirtualFile lookup can access existing VirtualFile instances. This is a especially useful in the case of temporary files (created from nested JARs), since multiple unpackings for nested JAR file related resources are not required.
By default there is no caching in VFS, since org.jboss.virtual.spi.cache.helpers.NoopVFSCache is used. You can provide your own cache implementation or choose from existing VFS implementations.
The cache implementations available as part of the org.jboss.virtual.plugins.cache package are:
SoftRefVFSCache
Uses soft reference as a map's entry value.
WeakRefVFSCache
Uses weak reference as a map's entry value.
TimedVFSCache
Evicts cache entries after the defaultLifetime.
LRUVFSCache
Evicts cache entries based on LRU, keeping minimum and maximum entries.
CombinedVFSCache
Holds few permanent roots. Any new root is cached in its realCache property.
By default, JBoss Enterprise Web Platform uses CombinedVFSCache. The cache type is configured in JBoss Microcontainer's bean configuration file, $JBOSS_HOME/server/$PROFILE/conf/bootstrap/vfs.xml, like so:
   <bean name="VFSCache">
     <constructor factoryClass="org.jboss.virtual.spi.cache.VFSCacheFactory" factoryMethod="getInstance">
       <!-- Use the CombinedVFSCache implementation -->
       <parameter>org.jboss.virtual.plugins.cache.CombinedVFSCache</parameter>
     </constructor>
     <start ignored="true"/>
     <property name="permanentRoots">
       <map keyClass="java.net.URL" valueClass="org.jboss.virtual.spi.ExceptionHandler">
         <entry>
           <key>${jboss.lib.url}</key>
           <value><null/></value>
         </entry>
         <entry>
           <key>${jboss.common.lib.url}</key>
           <value><inject bean="VfsNamesExceptionHandler"/></value>
         </entry>
         <entry>
           <key>${jboss.server.lib.url}</key>
           <value><inject bean="VfsNamesExceptionHandler"/></value>
         </entry>
         <entry>
           <key>${jboss.server.home.url}deploy</key>
           <value><inject bean="VfsNamesExceptionHandler"/></value>
         </entry>
       </map>
     </property>
     <property name="realCache">
       <bean class="org.jboss.virtual.plugins.cache.IterableTimedVFSCache"/>
     </property>
   </bean>
Any new custom VFS root (for example, an additional deploy directory) should be added to this configuration.
25.6.1.1.2. Annotation Scanning Tuning
There are currently three ways to limit resources scanning:
  • Provide a ScanningMetaData through XML or programmaticaly.
  • Add a new deployment filter to GenScanDeployer bean in deployers/metadata-deployer-jboss-beans.xml.
  • Modify JBossCustomDeployDUFilter in deployers/metadata-deployer-jboss-beans.xml.
ScanningMetaData can come from the jboss-scanning.xml file placed in your META-INF directory. This is a simple example of this file:
<scanning xmlns="urn:jboss:scanning:1.0">
  <path name="myejbs.jar">
    <include name="com.acme.foo"/>
    <exclude name="com.acme.foo.bar"/>
  </path>
  <path name="my.war/WEB-INF/classes">
    <include name="com.acme.foo"/>
  </path>
</scanning>
Here you list the paths inside your deployment, and which packages to include or exclude. If there is no explicit include, everything that is not excluded is included. If there is no path element at all, everything is excluded, as in the following example.
<scanning xmlns="urn:jboss:scanning:1.0">
<!-- Purpose: Disable scanning for annotations in contained deployment. -->
</scanning>
Another way to limit scanning is to provide the jboss-classloading.xml file, which contains classloader metadata.