Friday, 3 June 2011

Performance Tuning in JBoss AS

JBoss is an open source Java EE application server widely used for web development, testing and deployment. In this tutorial, I share some performance tips I recently applied on a number of JBoss servers for a telco company.

Performance has a significant impact on user experience, business and productivity, not to mention savings on hardware and software resources. For details on performance optimization and its benefits, I recommend this article.

Tuning is all about identifying bottlenecks! Performance bottlenecks are one of the nastiest to resolve: it could be due to poor AS configuration, bad coding, slow SQL statements, hardware limitations, etc. Surely though you'll aim to get the most out of your company's middleware investment :-) so upgrading the hardware is not an option.

This tutorial applies to JBoss version 4.x. Consider making a backup before changing any of your AS scripts.

General information before we start

To recap: processors, operating systems and applications can all be of 32 or 64 bit, as a result we get 32/64-bit CPU, OS and JVMs. For a more detailed explanation check out this article

If the processor (CPU) is 32-bit then the OS must also be 32-bit, however, if the CPU is 64-bit, then you can run both 32 and 64 bit OSes, just bear in mind that running a 32-bit OS on a 64-bit CPU means your memory can only go as high as 4GB (half of a 64-bit OS). In other words, The OS can only be installed if the hardware architecture supports it.

to find out whether the CPU is 32 or 64 bit, run the following on your Linux shell:

grep flags /proc/cpuinfo
lm (long mode): 64-bit
Protected mode: 32-bit
Real mode: 16-bit
Now, check whether your OS is 32-bit or 64 bit. Again from the Linux shell:

uname -m

Finally, try running your JVM in 64-bit mode:

java -d64 -version

1. Tuning JVM parameters

In JBoss, set your JAVA_HOME to point to your 64-bit JDK otherwise JBoss will probably run on its default 32-bit JVM. When you start JBoss, check the [Server Info] console log, It should say "64-bit Server VM", if not, you can activate the 64-bit JVM by adding the following inside run.conf file:


The run.conf file contains JVM parameters including memory configuration:

set JAVA_OPTS="$JAVA_OPTS -Xms3g -Xmx3g"
Note: Be careful not to set it too high, you need to give space to the native JVM.
Consider having fixed heap settings (same value for -Xms and -Xmx). If, for example, you only set "-Xmx" then the VM starts with a much smaller heap and re-sizes it. If your system, however, is under load for a relatively short period of time then you might want to set a smaller initial heap size so it can grow on demand. The actual heap size setting will depend on your application requirements and server RAM.

2. Garbage Collection

By default, JBoss RMI subsystem runs a full garbage collection every minute. Whether you're using RMI or not, all threads are paused and the entire heap is scanned. This can take a good time specially under load. You can change this behaviour to once an hour in run.conf.

This is set in the same way as the JVM parameters:

set JAVA_OPTS="... -Dsun.rmi.dgc.client.gcInterval=3600000

3. Stack Memory

Unlike the heap memory (whose size is controlled via -Xmx), the thread stack memory is not collected by the GC. JVM errors such as StackOverflowError and OutOfMemoryExceptions can also be related to the stack memory (where primitive vars and method call goes). Add the following to run.conf:

set JAVA_OPTS="... -XX:ThreadStackSize=256"
Note: 256K is the size of the thread, you can set 128 for smaller apps

The default thread stack memory space on 64-bit JVMs is 1M and 512K for 32-bit JVMs. Refer to Java Thread Stack Sizing doc for more details.

4. Turn off Debug Information in JSP Classes

By default, Apache's JSP compiler (Jasper) in JBoss, will compile JSP classes in debug mode. In production systems you should turn this off to increase the resources available to your application.

Edit file $JBOSS_HOME/server/default/jboss-web.deployer/conf/web.xml Add extra initialisation parameter (classdebuginfo) to the JspServlet:


5. Hot Deployment

It's recommended to disable Hot Deployment (HDScanner) in production as it can compromise performance and potentially expose security risks. Add the following in file: $JBOSS_HOME/server/default/conf/jboss-service.xml

<attribute name="ScanPeriod">BIG_NUMBER_IN_MS</attribute>
Note: Default is 5000ms (5 seconds)
Or alternatively, turn it off:

<attribute name="ScanPeriod">false</attribute>

6. Binding JBoss to IP addresses

As of version 4.2, JBoss binds all its services to the 'localhost' interface ( Which means it can only be accessed from the localhost. This change was done for security reasons, previously it was bound to any IP address ( by default.

On production, the default localhost interface ( configuration is not practical as the server will be accessed by different client IPs. Below are 3 options you can utilise to bind JBoss services to a desired IP or any network interface (
* Passing a parameter to the startup script
./ -b0.0.0.0
* Editing $JBOSS_HOME/bin/run.conf
Add the following at the end of the file: JAVA_OPTS="$JAVA_OPTS -Djboss.bind.address="
* Editing $JBOSS_HOME/server/default/deploy/jboss-web.deployer/server.xml
For all <Connector> elements, add the following attribute <Connector address=""


The above are just some of JBoss parameters you can play with. In my opinion, the most effective ones but for a comprehensive list of parameters please refer to the "Further Reading" section below. There's plenty of more stuff out there.

Note that while optimizing your application, as soon as one area improves another can become a bottleneck, therefore it's important to keep testing the application under stress conditions for each and every change. Performance tuning is an iterative process, you must repeat the cycle until you're happy with the results. Such tests are accomplished using load test tools like Apache JMeter and HP LoadRunner. I'm more familiar with Grinder but in case you're wondering which one to go for, here is a list of open source performance test tools.

Hasta luego!

Further Reading
1. Best practices for performance tuning
2. JBoss Optimization 101
3. Solving common Java EE performance problems
4. User Guide - JBoss Installation and Tuning

Tuesday, 3 May 2011

Hibernate Session Management in Spring

SpringSource came up with a set of template-based patterns (JdbcTemplate, HibernateTemplate, JpaTemplate, RestTemplate, etc) which basically takes care of all the necessary housekeeping, allowing you to concentrate on the logic of your application...anyways, I'm going to take a practical approach to hibernate session management in Spring using SpringHibernateTemplate.

Before we start, it's important to note that as of Spring 3 documentation, it is no longer recommended to use HibernateTemplate as it unnecessarily ties your code to Spring classes.

SpringHibernateTemplate is a Spring wrapper around the native Hibernate API. It adds an extra layer of abstraction on top of Hibernate making life a bit easier specially when it comes to session management.

3 Basic Steps:

1. Hibernate Mapping File:
Create the standard hibernate mapping file(s) for your class bean(s) just as you would on any Hibernate project, nothing interesting here, business as usual.

  • DB.CUSTOMER >> >> Customer.hbm.xml

2. DAO Implementation:
Here is where it all starts, define a second class CustomerSpringDao that extends HibernateDaoSupport so we can include database operations.

public class CustomerSpringDao extends HibernateDaoSupport
 public void addCustomer(Customer customer) {

 public Customer getCustomerAccountInfo(Customer customer) {
  Customer cust = null;
  List list = getHibernateTemplate().find("from Customer customer where customer.userId = ?" , customer.getUserId(),Hibernate.STRING);

  if(list.size() > 0){
   cust = (Customer) list.get(0);

  return cust;

This is a convenient super class for Hibernate-based data access objects. By extending this Spring abstract class you can make use of methods such as getHibernateTemplate() where you can perform hibernate operations without having to manage sessions manually. The SessionFactory is pre-initialized by the framework. Yep, that's right, it is completely abstracting the sessionFactory.openSession(), session.flush(), etc.

3. JDBC DataSource and HibernateSessionFactory Wiring
In the Spring framework, resources such as JDBC DataSource and HibernateSessionFactory can be realised as beans in the application context. Create the Spring Application Context file (if you haven't already created one) and place it in the classpath of your project. This file should reference your CustomerSpringDao class.

Putting it all toghether

Once you've completed all 3 steps, you will be ready to put it all into action. The following is an example on how you can access those spring beans and make use of spring's session management.

Before anything else, you can load the Spring application context XML file into a BeanFactory using the ClassPathXmlApplicationContext class, then go ahead persisting your object using common hibernate methods:

ClassPathXmlApplicationContext context = new

CustomerSpringDao csd = (CustomerSpringDao) context.getBean("eventDao", CustomerSpringDao.class);

// create customer object


Note, you're still free to use hibernate session if you like, all you have to do is access the hibernate session factory bean:

context.getBean("mySessionFactoryBean", SessionFactory.class);