[ Team LiB ] Previous Section Next Section

Best Practices

After thoroughly covering the more rigorous aspects of performance testing and tuning with WebLogic, it is time to look at some best practices, or rules of thumb, to keep in mind as you design and develop applications.

General Considerations

In general, make sure that you have the most recent versions of software and service packs for all parts of the system: database, JVM, OS, drivers, and so on. Sometimes software updates contain bug fixes that improve performance, or contain new optimizations (Not to mention fixes for security.) Also remember that, from the onset, high-level architecture design should always be mindful of performance. Changes to this level late in the development cycle often are not feasible. Low-level optimizations, on the other hand, should be reserved until later in the cycle—preferably until the last minute. Optimization at this level earlier in the cycle is less than fruitful because 80% of the execution time of an application is often consumed by 20% of its software.

Plan for Performance Testing

The idea behind testing is to execute your application in a setting that closely simulates the actual environment it will be running in. This means

  • Reproduce the production application environment— This includes hardware and external resources such as your database environment.

  • Attempt to accurately simulate actual user behavior— This includes determining the types of users that will be accessing the application and how they will use it.

  • Attempt to accurately simulate the number of actual users— This includes determining the maximum number of users per user type that will simultaneously be accessing the application.

  • Stress testing— Monitor application behavior as dependent resources such as database connections and memory are denied.

JRockit 8.1 Memory Management

On startup, the JRockit JVM is configurable, enabling you to mange memory allocations more effectively. Here are a number of parameters that you should pay special attention to:

  • -Xmx is the maximum heap size for the JVM. You will want to set this to the largest size possible. Doing so will reduce the amount of memory allocations required during times of high CPU usage. The chosen amount should be something less than the total amount of memory available on the machine. (The default value is 75% of available memory.) Be sure to consider the memory requirements of any additional applications running on the machine, however. The downside of specifying too large a heap size is that you may inadvertently cause excessive page faults, which can lead to a potential thrashing condition on the system. When an operating system runs low on memory, it must momentarily page any information it does not have room for to disk. When the paged information becomes needed, a page fault occurs and a read to disk is required to retrieve the missing information. Thrashing typically occurs when the operating system winds up spending an inordinate amount of time servicing page faults, and not enough time doing meaningful work. This will dramatically degrade the performance of your application.

  • -Xms is the initial heap size. Set this to the same size as the maximum heap size.

  • -Xns sets the size of the young generation (nursery). Set this higher if your application makes use of a large number of temporary objects.

EJB Tuning

The overhead associated with the creation and destruction of beans is expensive. To help alleviate this cost, WebLogic maintains a pool of pre-allocated beans to be served up to clients. There are a number of parameters that can be specified during the deployment process, which can have beneficial effects on performance. Practicing good design techniques will enhance performance as well.

EJB Pool Size

By default, WebLogic sets the maximum number of EJBs available in the free pool to an unlimited amount. The number of instances created is restricted only by the amount of memory you have allocated in the JVM settings we spoke of earlier. This should work fine for most applications and should not be changed. What you are seeking here is an optimal use of memory. If the number is lowered, it might result in increased object creation; if set higher more memory will be used.

Initial Beans in Free Pool

By default, WebLogic will not allocate any beans in the free pool at startup. It is a good practice to initialize some beans so that initial response times are not hindered by bean creation. You should set this number to the anticipated number of clients initially accessing the system under load.

Cache EJBHome Object References

When a client wants to access an EJB, it must first get an EJB Home object reference via the JNDI tree. It is good practice to create a cache of EJBHome objects that can be reused so as to alleviate the redundant process of JNDI lookups.

Release Resources

Just before a bean is removed from the pool, the EJB container will call the ejbRemove() method. Be sure to make use of this opportunity to release any resources that might have an effect on performance. For example, you might have acquired a Home object reference to another Session or Entity bean or a data source reference.

Session Façade

Network overhead is incurred every time you remotely access an Entity bean. Wrapping Entity beans within a Session bean reduces the number of network calls required by a client. For example, if a client wanted to access an online account, they might need to retrieve an AccountEntityBean, AddressEntityBean, BillingHistoryEntityBean, and so on. Each bean access requires its own network call. If you were to wrap these calls in an AccountManager Session bean, which in turn was responsible for processing the calls to the required Entity beans on the client's behalf, the transaction could be handled in one call. The Session bean will access the Entity beans locally, thus eliminating the remote calls and improving performance.

General Java Coding Tips

Given that WebLogic Server applications are written in Java, they can take full advantage of best coding practices as found in the language. Some specific examples of the kinds of optimization that can be gained by effective coding techniques are discussed in the following sections.

Recycle Java Objects

If you are constantly creating and discarding Java objects, you might get performance gains by creating an object factory that hands out instances of objects. When the instances are no longer needed, they are returned to the factory that can then issue them to another client. Although there is some overhead to maintaining the factory, the reduction in object creation can still improve performance. Use a Java profiler to spot frequent object creation in your code and use object factories where appropriate.

Cache Reusable Things

While your applications are executing, they will create things that can be reused later. This could be strings, database information, RMI method call results, and so on. Cache this information—you avoid the repeated overhead of having to re-create it each time. If you are running out of memory to store this information, go buy more memory. It is very cheap these days!

Use the Correct Java Collection

The Java Collections Framework includes many data structures that meet the requirements of many data scenarios. It is important to not only use the right Collection interface that gives you correct results, but also to use the one that gives you the best performance. Before choosing to use a collection, make sure that you understand the performance implications of choosing it. For example, a TreeMap enables you to iterate through a set in an ordered manner, whereas a HashMap allows for quicker key lookups.

TIP

You can find additional Java coding tips at http://www.javaperformancetuning.com/tips/rawtips.shtml. This page contains thousands of optimization tips for Java.


    [ Team LiB ] Previous Section Next Section