Skip Headers

Oracle9i Application Server Performance Guide
Release 2 (9.0.2)

Part Number A95102-02
Go To Documentation Library
Go To Product List
Solution Area
Go To Table Of Contents
Go To Index

Go to previous page Go to next page

Optimizing J2EE Applications In OC4J

This chapter provides guidelines for improving the performance of Oracle9iAS Containers for J2EE (OC4J) applications in Oracle9i Application Server.

This chapter contains:


This chapter describes using Oracle Enterprise Manager for setting OC4J and application configuration options. You can also use the Distributed Configuration Management (DCM) utility, dcmctl, to set configuration options. This utility provides a command-line alternative to using Oracle Enterprise Manager for some Oracle9iAS configuration and management tasks.

OC4J J2EE Application Performance Quickstart

This section provides a quickstart for tuning J2EE applications that run on OC4J, providing links for information on important performance issues.

Table 6-1 lists a quick guide for performance issues for J2EE applications.

Table 6-1  Critical Performance Areas for J2EE Applications
Performance Area Description and Reference

Providing Adequate Memory Resources

To improve the performance of your J2EE applications, provide adequate memory resources. If the OC4J running your J2EE applications does not have enough memory, performance can suffer due to the overhead required to manage limited memory

See "Setting the JVM Heap Size for OC4J Processes"

Caching and Reusing Database Connections

Setting up database connection pooling properly is often a critical performance consideration for J2EE applications that access a database. Data sources provide configuration options that allow you to use and configure pooled database connections.

See "Setting Up Data Sources - Performance Issues"

Managing Concurrency and Limiting Connections

See "Limiting HTTP Connections"

Load Balancing

See "Configuring Multiple OC4J Processes"

Balancing Applications

See "Balancing Applications Across OC4J Instances"

Database Monitoring and Tuning

See "Database Monitoring and Tuning"

Improving J2EE Application Performance by Configuring OC4J Instance

Tuning OC4J configuration options allows you to improve the performance of J2EE applications running on an OC4J Instance. Modifying the configuration may require balancing the available resources on your system with the performance requirements for your applications.

This section covers configuration changes that can affect J2EE application performance and includes the following topics:

Setting Java Options for OC4J Processes

When running Oracle9iAS, the module mod_oc4j is the connector from Oracle HTTP Server to one or more OC4J Instances. Each OC4J process within an OC4J Instance runs in its own Java Virtual Machine (JVM) and is responsible for parsing J2EE requests and generating a response. When a request comes into Oracle HTTP Server, mod_oc4j picks an OC4J process and routes the request to the selected OC4J process. Within each OC4J Instance all of the OC4J JVM processes use the same configuration and start with the same Java options. Likewise, unless a process dies or there is some other problem, each OC4J process that is part of an OC4J Instance has the same J2EE applications deployed to it.

Depending on your J2EE application, you may be able to improve the application's performance by setting Java Options for the JVM running OC4J where your application is deployed.

Setting the JVM Heap Size for OC4J Processes

If you have sufficient memory available on your system and your application is memory intensive, you can improve your application performance by increasing the JVM heap size from the default values. While the amount of heap size required varies based on the application and on the amount of memory available, for most OC4J server applications, a heap size of at least 128 Megabytes is advised. If you have sufficient memory, using a heap size of 256 Megabytes or larger is preferable.

To change the size of the heap allocated to the OC4J processes in an OC4J Instance, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the following Java options:

-Xmssizem -Xmxsizem

Where size is the desired Java heap size in megabytes.

If you know that your application will consistently require a larger amount of heap, you can improve performance by setting the minimum heap size equal to the maximum heap size, by setting the JVM -Xms size to be the same as the -Xmx size.

For example, to specify a heap size of 128 megabytes, specify the following:

-Xms128m -Xmx128m

You should set your maximum Java heap size so that the total memory consumed by all of the JVMs running on the system does not exceed the memory capacity of your system. If you select a value for the Java heap size that is too large for your hardware configuration, one or more of the OC4J processes within the OC4J Instance may not start, and Oracle Enterprise Manager reports an error. Review the log files for the OC4J Instance in the directory $ORACLE_HOME/opmn/logs, to find the error report:

Could not reserve enough space for object heap
Error occurred during initialization of VM

If you select a value for the JVM heap size that is too small, none of the OC4J processes will be able to start, and Oracle Enterprise Manager reports an error. If you review the log files for the OC4J Instance in the directory $ORACLE_HOME/opmn/logs, you may find errors similar to the following:



There are other reasons why java.lang.OutOfMemoryError error may occur. For example, if the application has a memory leak.

If the system runs out of memory, the OC4J process will shut down. This will happen if references to the objects are not released. For example, if objects are stored in a hash table or vector and never again removed.

It is of course possible that your process actually needs to use a lot of memory. In this case, the maximum heap size for the process should be increased to avoid frequent garbage collection.

To maximize performance, set the maximum heap size to accommodate application requirements. To determine how much Java heap you need, include calls in your program to the Runtime.getRuntime().totalMemory() and Runtime.getRuntime().freeMemory methods in the java.lang package. Subtract free memory from total memory; the difference is the amount of heap that the application consumed.

See Also:

You can find detailed information about JVM options and their impact on performance on the JVM vendor's web sites.

Setting the Server Option for OC4J Processes (for UNIX)

Depending on the particular J2EE application, setting the command line option -server for the JVM running OC4J may improve performance (the JVM runs in one of two modes set with the two related options, -client and -server, the default value is -client). To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -server Java option.


Do not use the -server option when running OC4J on Oracle9i Application Server for Windows systems. Our tests indicate that using the -server option on JVMs running OC4J on Windows systems does not improve and may degrade performance.

The -server option selects the server VM instead of using the default client VM. The client and the server VMs are similar, except that the server VM is specially tuned to maximize peak operating speed. It is intended for executing long-running server applications, for which having the fastest possible operating speed is generally more important than having a fast startup time or a smaller runtime memory footprint. The client VM, the default without using the -server option starts up faster and requires a smaller memory footprint than the server VM.


The -server option must be specified first, before all other Java options.

Setting the Stack Size Option for OC4J Processes

Depending on the particular J2EE application, changing the setting of the command line option -Xss for the JVM running OC4J may improve performance. To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -Xss Java option.

This option sets the maximum stack size for C code in a thread to n. Every thread that is spawned during the execution of the program passed to java has n as its C code stack size. The default C code stack size is 512 kilobytes (-Xss512k). A value of 64 kilobytes is the smallest amount of C code stack space allowed per thread.

Oracle recommends that you try the following value to improve the performance of your J2EE applications:


Setting the Concurrentio Option for OC4J Processes

Depending on the particular J2EE application and JDK version, changing the setting of the command line option -Xconcurrentio for the JVM running OC4J may improve performance. To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -Xconcurrentio Java option.

This option generally helps programs with many threads. The main feature turned on with -Xconcurrentio is to use LWP based synchronization instead of thread based synchronization. For certain applications, with JDK 1.3.1, this option increases speed up by over 40%. See the following site for more information,

Using the -Xconcurrentio option, it is important to compare results for your application without the option. In some tests, results have been mixed, using the option results in a speedup for some applications, but for other applications or JDK versions, the performance degraded with this option. See the following site, 


In JDK 1.4, LWP based synchronization is the default, but setting -Xconcurrentio can still improve performance in JDK 1.4 since it turns on additional internal options.

Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options

To change the Java command line options for an OC4J Instance, go to the home page for the OC4J Instance and perform the following steps:

  1. Stop the OC4J Instance.

  2. Drill down to the Server Properties page.

  3. In the Command Line Options area of the Server Properties page, under the heading Multiple VM Configuration, set the Java Options.

    For example, enter the following to set the JVM heap sizes to 128 Megabytes:

  4. Use the Apply button to apply the changes.

  5. Start the OC4J Instance.

Figure 6-1 shows the Server Properties page with Java Options.

Figure 6-1 Setting Java Heap Size for an OC4J Instance Using Oracle Enterprise Manager

Text description of em_vmconfig.gif follows.

Text description of the illustration em_vmconfig.gif

Setting Up Data Sources - Performance Issues

A data source, which is the instantiation of an object that implements the javax.sql.DataSource interface, enables you to retrieve a connection to a database server. This section describes data source configuration options for global data sources. A global data source is available to all the deployed applications in an OC4J Instance.

This section covers the following topics:

Emulated and Non-Emulated Data Sources

Some of the performance related configuration options have different affects, depending on the type of the data source. OC4J supports two types of data sources, emulated and non-emulated:

The pre-installed default data source is an emulated data source. Emulated data sources are wrappers around Oracle data sources. If you use these data sources, your connections are extremely fast, because they do not provide full XA or JTA global transactional support. We recommend that you use these data sources for local transactions or when your application requires access or update to a single database. You can use emulated data sources for Oracle or non-Oracle databases.

You can use the emulated data source to obtain connections to different databases by changing the values of the url and connection-driver parameters.

The following is a definition of an emulated data source:


Non-emulated data sources are pure Oracle data sources. These are used by applications that want to coordinate access to multiple sessions within the same database or to multiple databases within a global transaction.

Using the EJB Aware Location Specified in Emulated Data Sources

Each data source is configured with one or more logical names that allow you to identify the data source within J2EE applications. The ejb-location is the logical name of an EJB data source. In addition, use the ejb-location name to identify data sources for most J2EE applications, where possible, even when not using EJBs. The ejb-location only applies to emulated data sources. You can use this option for single phase commit transactions or emulated data sources.

Using the ejb-location, the data source manages opening a pool of connections, and manages the pool. Opening a connection to a database is a time-consuming process that can sometimes take longer than the operation of getting the data itself. Connection pooling allows client requests to have faster response times, because the applications do not need to wait for database connections to be created. Instead, the applications can reuse connections that are available in the connection pool.


Oracle recommends that you only use the ejb-location JNDI name in emulated data source definitions for retrieving the data source. For non-emulated data sources, you must use the location JNDI name.

Setting the Maximum Open Connections in Data Sources

The max-connections option specifies the maximum number of open connections for a pooled data source. To improve system performance, the value you specify for the number max-connections depends on a combination of factors including the size and configuration of your database server, and the type of SQL operations that your application performs.

The default value for max-connections and the handling of the maximum depends on the data source type, emulated or non-emulated.

For emulated data sources, there is no default value for max-connections, but the database configuration limits that affect the number of connections apply. When the maximum number of connections, as specified with max-connections, are all active, new requests must wait for a connection to be become available. The maximum time to wait is specified with wait-timeout.

For non-emulated data sources, there is a property, cacheScheme, that determines how max-connections is interpreted. Table 6-2 lists the values for the cacheScheme property (DYNAMIC_SCHEME is the default value for cacheScheme).

See Also:

Table 6-2  Non-emulated Data Source cacheScheme Values
Value Description


In this scheme, when the maximum limit is reached, a request for a new connection waits until another client releases a connection.


In this scheme, the maximum limit cannot be exceeded. Requests for connections when the maximum has already been reached return null.


In this scheme, you can create new pooled connections above and beyond the maximum limit, but each one is automatically closed and freed as soon as the logical connection instance is finished being used, where it is returned to the available cache.

DYNAMIC_SCHEME is the default value for cacheScheme.

The tradeoffs for changing the value of max-connections are:

Setting the Minimum Open Connections in Data Sources

The min-connections option specifies the minimum number of open connections for a pooled data source.

For applications that use a database, performance can improve when the data source manages opening a pool of connections, and manages the pool. This can improve performance because incoming requests don't need to wait for a database connection to be established; they can be given a connection from one of the available connections, and this avoids the cost of closing and then reopening connections.

By default, the value of min-connections is set to 0. When using connection pooling to maintain connections in the pool, specify a value for min-connections other than 0.

For emulated and non-emulated data sources, the min-connections option is treated differently.

For emulated data sources, when starting up the initial min-connections connections, connections are opened as they are needed and once the min-connections number of connections is established, this number is maintained.

For non-emulated data sources, after the first access to the data source, OC4J then starts the min-connections number of connections and maintains this number of connections.

Limiting the total number of open database connections to a number your database can handle is an important tuning consideration. You should check to make sure that your database is configured to allow at least as large a number of open connections as the total of the values specified for all the data sources min-connections options, as specified in all the applications that access the database.


If the min-connections is set to a value other than zero, the specified number of connections will be maintained; OC4J maintains the connections when they are not in use, and they do not time out when the specified inactivity-timeout is reached.

Once the specified connections are opened, OC4J does not provide a way to close the connections, except by stopping OC4J.

Setting the Cached Connection Inactivity Timeout in Data Sources

The inactivity-timeout specifies the time, in seconds, to cache unused connections before closing them.

To improve performance, you can set the inactivity-timeout to a value that allows the data source to avoid dropping and then re-acquiring connections while your J2EE application is running.

The default value for the inactivity-timeout is 60 seconds, which is typically too low for applications that are frequently accessed, where there may be some inactivity between requests. For most applications, to improve performance, we recommend that you increase the inactivity-timeout to 120 seconds.

To determine if the default inactivity-timeout is too low, monitor your system. If you see that the number of database connections grows and then shrinks during an idle period, and grows again soon after that, you have two options: you can increase the inactivity-timeout, or you can increase the min-connections.

See Also:

Setting the Wait for Free Connection Timeout in Data Sources

The wait-timeout specifies the number of seconds to wait for a free connection if the connection pool does not contain any available connections (that is, the number of connections has reached the limit specified with max-connections and they are all currently in use).

If you see connection timeout errors in your application, increasing the wait-timeout can prevent the errors. The default wait-timeout is 60 seconds.

If database resources, including memory and CPU are available and the number of open database connections is approaching max-connections, you may have limited max-connections too stringently. Try increasing max-connections and monitor the impact on performance. If there are not additional machine resources available, increasing max-connections is not likely to improve performance.

You have several options in the case of a saturated system:

Setting the Connection Retry Interval in Data Sources

The connection-retry-interval specifies the number of seconds to wait before retrying a connection when a connection attempt fails.

If the connection-retry-interval is set to a small value, or a large number of connection attempts is specified with max-connect-attempts this may degrade performance if there are many retries performed without obtaining a connection.

The default value for the connection-retry-interval is 1 second.

Setting the Maximum Number of Connection Attempts in Data Sources

The max-connect-attempts option specifies the maximum number of times to retry making a connection. This option is useful to control when the network is not stable, or the environment is unstable for any reason that sometimes makes connection attempts fail.

If the connection-retry-interval option is set to a small value, or a large number of connection attempts is specified with max-connect-attempts this may degrade performance if there are many retries performed without obtaining a connection.

The default value for max-connect-attempts is 3.

Using Oracle Enterprise Manager to Change Data Source Configuration Options

Figure 6-2 shows the Oracle Enterprise Manager configuration page that lets you view or modify a data source. This page is available in Oracle Enterprise Manager by selecting the Edit button for a selected data source from the Data Sources page from the application default page for an OC4J Instance, or by selecting data sources from the administration section of a deployed application's description page (this is only available when the application has its own local data source).

Oracle Enterprise Manager stores the data sources elements that you add or modify in an XML file. This file defaults to the name data-sources.xml and is located in /j2ee/home/config. If you want to change the name or the location of this file, you can do this in the General Properties page off of the default application screen or off of your specific application's page, when the application specifies a local data source.


You can also use the Oracle Enterprise Manager Advanced Properties links to create or edit data sources. This allows you to add data sources using the XML definitions which is useful if you have been provided the XML.

Figure 6-2 Oracle Enterprise Manager Data Sources Configuration Page

Text description of em_datasourceconfig.gif follows.

Text description of the illustration em_datasourceconfig.gif

Improving Servlet Performance in Oracle9iAS

This section discusses configuration options and performance tips specific to servlets for optimizing OC4J performance.

This section covers the following topics:

Improving Performance by Altering Servlet Configuration Parameters

This section cover the following:

Loading Servlet Classes at Startup

By default, OC4J loads a servlet when the first request is made. OC4J also allows you to load servlet classes when the JVM that runs the servlet is started. To do this, add the <load-on-startup> sub-element to the <servlet> element in the application's web.xml configuration file.

For example, add the <load-on-startup> as follows:


Using the load-on-startup facility increases the start-up time for your OC4J process, but decreases first-request latency for servlets.

Using Oracle Enterprise Manager you can also specify that OC4J load for an entire Web Module on startup. To specify that a web module is to be loaded on startup, select the Website Properties page for an OC4J Instance and then use the Load on Startup checkbox.

Servlet Performance Tips

The following tips can enable you to avoid or debug potential performance problems:

Analyze Servlet Duration

It is useful to know the average duration of the servlet (and JSP) requests in your J2EE enterprise application. By understanding how long a servlet takes when the system is not under load, you can more easily determine the cause of a performance problem when the system is loaded. The average duration of a given servlet is reported in the metric service.avg for that servlet. You should only examine this value after making many calls to the servlet so that any startup overhead such as class loading and database connection establishment will be amortized.

As an example, suppose you have a servlet for which you notice the service.avg is 32 milliseconds. And suppose you notice a response time increase when your system is loaded, but not CPU bound. When you examine the value of service.avg, you might find that the value is close to 32 ms, in which case you can assume the degradation is probably due to your system or application server configuration rather than in your application. If on the other hand, you notice that service.avg has increased significantly, you may look for the problem in your application. For example, multiple users of the application may be contending for the same resources, including but not limited to database connections.

See Also:

Table A-11 in Appendix A, "Oracle9iAS Performance Metrics"

Understand Server Request Load

In debugging servlet and JSP problems, it is often useful to know how many requests your OC4J processes are servicing. If the problems are performance related, it is always helpful to know if they are aggravated by a high request load. You can track the requests for a particular OC4J Instance using Oracle Enterprise Manager, or by viewing the application's web module metrics.

See Also:

Table A-11 in Appendix A, "Oracle9iAS Performance Metrics"

Find Large Servlets That Require a Long Load Time

You may find that a servlet application is especially slow the first time it is used after the server is started, or that it is intermittently slow. It is possible that when this happens the server is heavily loaded, and the response time is suffering as a result. If there is no indication of a high load, however, which you can detect by monitoring your access logs, periodically monitoring CPU utilization, or by tracking the number of users that have active requests on the HTTP server and OC4J, then you may just have a large servlet that takes a long time to load.

You can see if you have a slow loading servlet by looking at service.maxTime, service.minTime, and service.avg. If the time to load the servlet is much higher than the time to service, the first user that accesses the servlet after your system is started will feel the impact, and service.maxTime will be large. You can avoid this by configuring the system to initialize your servlet when it is started.

See Also:

"Loading Servlet Classes at Startup"

Watch for Unused Sessions

You should regularly monitor your applications looking for unused sessions. It is easy to inadvertently write servlets that do not invalidate their sessions. Without source code for the application software, you may not know this could be a problem on your host, but sooner or later you would notice a higher consumption of memory than expected. You can see if there are sessions which are not utilized or sessions which are not being properly invalidated after being used with the session metrics, including: sessionActivation.time and sessionActivation.completed and

See Also:

Table A-12 in Appendix A, "Oracle9iAS Performance Metrics"

Watch for Abnormal Session Usage

This example shows an application that creates sessions, but never uses them:

To provide an example, we show metrics from a JSP under /oc4j/application/WEBs/context:       500 ops
session.Activation.completed:      0 ops

This application created 500 sessions and all are still active. Possibly, this indicates that the application makes unnecessary use of the sessions and it is just a matter of time before it causes memory or CPU consumption problems.

A well-tuned application shows with a value that is less than sessionActivation.completed before the session time out. This indicates that the sessions are probably being used and cleaned up.

Suppose we have a servlet that uses sessions effectively and invalidates them appropriately. Then we might see a set of metrics such as the following, under /oc4j/<application>/WEBs/<context>:         2 ops
session.Activation.completed:    500 ops

The fact that two sessions are active when more than 500 have been created and completed indicates that sessions are being invalidated after use.

Load Servlet Session Security Routines at Startup

OC4J uses the class for secure seed generation. The very first call to this method is time consuming. Depending on how your system is configured for security, this method may not be called until the very first request for a session-based servlet is received by the Application Server. One alternative is to configure the application to load-on-startup in the application's web.xml configuration file and to create an instance of SecureRandom during the class initialization of the application. The result will be a longer startup time in lieu of a delay in servicing the first request.

See Also:

"Loading Servlet Classes at Startup"

Improving JSP Performance in Oracle9iAS

OracleJSP is Oracle's implementation of the Sun Microsystems JavaServer Pages specification. Some of the additional features it includes are custom JavaBeans for accessing Oracle databases, SQL support, and extended datatypes.

This section explains how you can improve OracleJSP performance. It contains the following topics:

Oracle9iAS provides JSP tag libraries that include some features that may improve the performance of J2EE applications. For example, you may be able to use the JSP caching features available in the tag libraries to increase the speed and scalability for your applications:

Improving Performance by Altering JSP Configuration Parameters

This section describes JSP configuration parameters that you can alter to improve and control JSP operation. These parameters are set for each OC4J Instance, by altering the file global-web-application.xml.

See Also:

Using the main_mode Parameter

The main_mode parameter determines whether classes are automatically reloaded or JSPs are automatically recompiled, in case of changes.

Table 6-3 shows the supported settings for main_mode.

Table 6-3  JSP main_mode Parameter Values
Option Description


The runtime dispatcher does not perform any timestamp checking, so there is no recompilation of JSPs or reloading of Java classes. This mode is the most efficient mode for a deployment environment, where code will not change.

If comparing timestamps is unnecessary, as is the case in a typical production deployment environment where source code will not change, you can avoid all timestamp comparisons and any possible retranslations and reloads by setting the main_mode parameter to the value justrun.

Using this value can improve the performance of JSP applications.

Note: before you set main_mode to the value justrun, make sure that the JSP is compiled at least once. You can compile the JSP by invoking it through a browser, or by running your application (using the default value for main_mode, recompile). This assures that the JSP is compiled before you set the justrun flag.


The dispatcher will check if any classes have been modified since loading, including translated JSPs. JavaBeans invoked from pages, and any other dependency classes.


This is the default value for main_mode.

The dispatcher will check the timestamp of the JSP, retranslate it if it has been modified since loading, and execute all reload functionality as well.

Note the following when working with the main_mode parameter:

Improving Performance by Tuning JSP Code

This section describes changes you can make to your JSP code to improve performance.

This section covers the following topics:

Impact of Session Management on Performance

In general, sessions add performance overhead for your Web applications. Each session is an instance of the javax.servlet.http.HttpSession class. The amount of memory per session depends on the size of the session objects created. You can turn off sessions for your JSPs if you do not want a new session created for each request. By default, in OracleJSP sessions are enabled. If you do not need to use sessions in your JSPs, turn them off by including the following line at the top of the JSP:

<%@ page session="false" %>

If you use sessions, ensure that you explicitly cancel the session. If you do not cancel a session, it remains active until it times out. Invoke the invalidate() method to cancel a session.

The default session timeout for OC4J is 30 minutes. You can change this for a specific application by setting the <session-timeout> parameter in the <session-config> element of web.xml.

For example, the following code shows how you would cancel a session after you have finished using it:

HtttpSession session;
session = httpRequest.getSession(true);

OC4J uses the class for secure seed generation. The very first call to this method is time consuming. Depending on how your system is configured for security, this method may not be called until the very first request for a session-based JSP is received by the Application Server. One alternative is to force this call to be made on startup by including a call in the class initialization for some application that is loaded on startup. The result will be a longer startup time in lieu of a delay in servicing the first request.


JSP pages by default use sessions while servlets by default do not use sessions.

See Also:

Using Static Template Text Instead of out.print for Outputting Text

Using the JSP code out.print("<html>") requires more resources than including static template text. For performance reasons, it is best to reserve the use of the out.print() command for dynamic text.

Example 6-1 and Example 6-2 are two HTML coding examples. For these JSP samples, Example 6-2 should be more efficient and give better performance.

Example 6-1 Using out.print

  out.print("<HTML> <HEAD> <TITLE>Bookstore Home Page</TITLE></HEAD>\n");
  out.print("<BODY BGCOLOR=\"#ffffff\">\n");
  out.print("<H1 ALIGN=\"center\">Book Store Web Commerce Test</H1>\n");
  out.print("<P ALIGN=\"CENTER\">\n");
  out.print("<IMG SRC=\"../bookstore/Images/booklogo.gif\" ALIGN=\"BOTTOM\""+
              "BORDER=\"0\" WIDTH=\"288\" HEIGHT=\"67\"></P>\n");
  out.print("<H2 ALIGN=\"center\">Home Page</H2>\n");
<jsp:useBean  id="randomid"  class="bookstore.BOOKS_Util" scope="request" >
  random_id = randomid.getRandomI_ID();

Example 6-2 Using Static Text

<HTML> <HEAD> <TITLE>Bookstore Home Page</TITLE></HEAD>
<BODY BGCOLOR=\"#ffffff\">
<H1 ALIGN=\"center\">Bookstore Web Commerce Test </H1>
<IMG SRC=\"../bookstore/Images/booklogo.gif\" ALIGN=\"BOTTOM\""+
         "BORDER=\"0\" WIDTH=\"288\" HEIGHT=\"67\"></P>
<H2 ALIGN=\"center\">Home Page</H2>
<jsp:useBean  id="randomid"  class="bookstore.BOOKS_Util" scope="request" >
  random_id = randomid.getRandomI_ID();

Performance Issues for Buffering JSPs

By default, a JSP uses an area of memory known as a page buffer. The page buffer, set to 8KB by default, is required if the JSP uses dynamic globalization, contextType settings, error pages, or forwards. If the page does not use these features, then you can disable buffering with the following command:

<%@ page buffer="none" %>

Disabling buffering by setting the buffer value to none improves the performance of the page by reducing memory usage and saving the processing step of copying the buffer.

When you need buffering, it is important to select an adequate size for your buffer. If you are writing a page that is larger than the default 8KB buffer, and you have not reset the buffer size, then the JSP autoflush will be activated which could have performance implications. Therefore, if buffering is necessary for your JSP, make sure to set the page buffer to an appropriate size. For example, to set the buffer size to 24KB, use the following command:

<%@ page buffer="24KB" %>

Using Static Versus Dynamic Includes

The include directive makes a copy of the included page and copies it into a JSP (including page) during translation. This is known as a static include (or translate-time include) and uses the following syntax:

<%@ include file="/jsp/userinfopage.jsp" %>

Alternatively, the jsp:include tag dynamically includes output from the included page within the output of the including page, during runtime. This is known as a dynamic include (or runtime include) and uses the following syntax:

<jsp:include page="/jsp/userinfopage.jsp" flush="true" />

If you have static text, that is not too large, for performance reasons, it is better to use a static include rather than a dynamic include.

In general, when working with includes, note the following:

Performance Issues for Including Static Content

JSPs containing a large amount of static content, including large amounts of HTML code that does not change at runtime, may result in slow translation and execution.

There are two workarounds for this issue that may improve performance:

Improving EJB Performance in Oracle9iAS

This section covers configuration parameters that you set to control how OC4J handles EJBs. Tuning these options can improve the performance of EJBs running on OC4J.

This section includes the following topics:

Setting server.xml Configuration Parameters for EJBs

This section covers parameters that you can tune for EJB performance in the server.xml file for an OC4J Instance.

Setting the Transaction Configuration Timeout

You can change the default value for the transaction configuration timeout in the transaction-config element in the server.xml file for the OC4J Instance. The transaction-config timeout is not an EJB specific timeout, but affects all transactions which use EJBs. This configuration parameter specifies the maximum time taken for a transaction to finish before it can get rolled back due to a timeout. This parameter applies to all transactions on the OC4J Instance. The default value for this parameter is 60000 milliseconds (60 seconds).

For example, the following server.xml sets the transaction-config timeout parameter to 30 seconds:

<transaction-config timeout="30000"/>

Increase this value if your applications that use transactions are getting transaction timeout errors, or if your transactions may be longer than 60 seconds (including waiting for connections set by wait-timeout in datasources.xml).

The transaction-config timeout applies for all transactions running in OC4J, and therefore must be big enough for your longest transaction. If you specify a small timeout value for transaction-config timeout, then you cannot set the timeout to a larger value for an individual EJB, since the transaction-config timeout applies for all transactions at the EJB level. Thus, the timeout should be set to a value greater than or equal to the timeouts used within a transaction (for example the data sources wait-timeout, and the EJB call-timeout).

See Also:

Setting OC4J Specific Configuration Parameters for EJBs

This section covers parameters that you can tune for EJB performance that are specific to OC4J. These parameters are set in the orion-ejb-jar.xml file.

This section covers the following topics:

Configuring Parameters that Apply for All EJBs

Table 6-4 lists parameters that you can tune for EJB performance that are specific to OC4J. These parameters apply for all types of EJBs, including session and entity beans. The parameters in Table 6-4 are specified in orion-ejb-jar.xml.

Table 6-4  EJB Parameters That Apply for All EJB Types
Parameter Description


Applies for session and entity beans. This parameter specifies the maximum time to wait for any resource that the EJB container needs, excluding database connections, before the container calls the EJB method.

Default Values: 90000 milliseconds for entity beans and 0 (forever) for session beans.

See Also: "Setting the Transaction Configuration Timeout"


Applies for session and entity beans. This parameter specifies the number of times to retry a transaction that was rolled back due to system-level failures.

Generally, we recommend that you start by setting max-tx-retries to 0 and adding retries only where errors are seen that could be resolved through retries. For example, if you are using serializable isolation and you want to retry the transaction automatically if there is a conflict, you might want to use retries. However, if the bean wants to be notified when there is a conflict, then in this case, you should set max-tx-retries=0.

Default Value: 3 (for session beans and entity beans)

See Also: "Setting the Transaction Configuration Timeout"

See Also: "Setting the Connection Retry Interval in Data Sources"

Configuring Parameters for CMP Entity Beans

This section covers parameters for entity beans using CMP. These parameters are specified in the orion-ejb-jar.xml configuration file that affect performance.

Table 6-5 lists the entity bean CMP specific parameters.

Table 6-6 describes the supported locking-mode parameter values.

Table 6-5  CMP Entity Bean Performance Parameters and Descriptions
Parameter Description


For a description, see Table 6-4


Recommend setting to false to avoid the extra select before insert which checks if the entity already exists before doing the insert. This will then detect a duplicate, if there is one, during the insert.

Default Value: true


Default is false for beans with locking-mode=optimistic or pessimistic and true for locking-mode=read-only.

This parameter corresponds to which commit option is used (A, B or C, as defined in the EJB specification). When exclusive-write-access = true, this is commit option A.

The exclusive-write-access is forced to false if locking is pessimistic or optimistic, and is not used with EJB clustering. The exclusive-write-access can be false with read-only locking, but read-only won't have any performance impact if exclusive-write-access=false, since ejbStores are already skipped when no fields have been changed. To see a performance advantage and avoid doing ejbLoads for read-only beans, you must also set exclusive-write-access=true.


If your database is already configured with the isolation mode you want for your transactions, you'll get better performance if you don't explicitly set the isolation mode attribute in the orion-ejb-jar.xml file. Omitting the isolation setting means to use the database default setting, and extra processing will not be done to explicitly set isolation levels in your transactions.

See Table 6-7 for a description of isolation options and how they relate to locking modes.

Default value:


The locking modes, specified with the locking-mode parameter, manage concurrency and configure when to block to manage resource contention or when to execute in parallel.

See Table 6-6 for a description of locking-mode.

See Table 6-7 for a description of isolation options and how they relate to locking modes.


For a description, see Table 6-4


Specifies whether the container updates only modified fields or all fields to persistence storage for CMP entity beans when ejbStore is invoked.

Default Value: true


The validity-timeout is only used when exclusive-write-access=true and locking-mode=read-only.

The validity timeout is the maximum time in milliseconds that an entity is valid in the cache (before being reloaded). We recommend that if the data is never being modified externally (and therefore you've set exclusive-write-access=true), that you can set this to 0 or -1, to disable this option, since the data in the cache will always be valid for read-only EJBs that are never modified externally.

If the EJB is generally not modified externally, so you're using exclusive-write-access=true, yet occasionally the table is updated so you need to update the cache occasionally, then set this to a value corresponding to the interval you think the data may be changing externally.


The following CMP entity bean parameters are not supported in this release:

max-instances, min-instances, pool-cache-timeout

Table 6-6  CMP Entity Bean Locking-Mode Values
Locking Mode Value Description


Multiple users can execute the entity bean in parallel. The optimistic locking mode does not monitor resource contention; thus, the burden of the data consistency is placed on the database isolation modes.

This is the default value for locking-mode.


Manages resource contention and does not allow parallel execution. Only one user at a time is allowed to execute the entity bean. Pessimistic locking uses "SELECT....FOR UPDATE" to serialize access in the database.


Multiple users can execute the entity bean in parallel. The container does not allow any updates to the bean's state.

The locking-mode, along with isolation, assures database consistency for EJB entity beans using CMP. Table 6-7 shows the common locking-mode and isolation combinations. The different combinations have both functional and performance implications, but often the functional requirements for data consistency will lead to selecting a mode, even when it may be at the expense of performance.

Table 6-7  CMP Entity Bean Locking-Mode and Isolation Relationships
Locking-mode Isolation When to Use



If data consistency must be guaranteed, and frequent concurrent updates to the same rows are expected.



We recommend that this combination not be used.



If concurrent reads and updates to the same rows with read-committed semantics is sufficient.



If data consistency must be guaranteed, but infrequent concurrent updates to the same rows are expected.



If repeatable read is not required.



If repeatable read is required.

In Table 6-7 the isolation setting refers to either the transaction isolation attribute setting, if explicitly set, or to the database isolation level (if the transaction isolation attribute is not set). Also, although locking-mode and transaction isolation levels are set as attributes of a CMP bean, the isolation level that will be in effect for the transaction is the isolation level of the first entity bean used in the transaction. Therefore it is best to set all beans in the same transaction to the same isolation level.

In general, optimistic locking with committed isolation will be faster since it allows for more concurrency, but it may not meet your needs for data consistency. Pessimistic locking with committed isolation, and optimistic locking with serializable isolation will be slower, but will guarantee data consistency on updates.

Defining a bean as read-only will assure that no updates are allowed to the bean. The performance will be similar to a bean which may not be defined as read-only, and yet is never used to do inserts, updates, or deletes (i.e. only the methods which read are called). This is because if no fields are modified in a bean that is not defined with read-only locking, it is already optimized to not do an ejbStore. To see a performance advantage and avoid doing ejbLoads for read-only beans, you must also set exclusive-write-access=true.

Configuring Parameters for BMP Entity Beans

This section covers parameters that apply to entity beans using BMP. These parameters are specified in the orion-ejb-jar.xml configuration file.

Table 6-8 lists the entity bean BMP specific parameters.

Table 6-8  BMP Entity Bean Performance Parameters and Descriptions
Parameter Description


For a description, see Table 6-4


The locking modes, specified with the locking-mode parameter, manage concurrency and configure when to block to manage resource contention or when to execute in parallel.

BMP beans must use optimistic locking, which allows concurrent access to a bean, and the BMP bean is responsible for managing the database access and data consistency. It is up to the BMP bean to manage isolation as well, and therefore the isolation settings do not apply for BMP

Default Value: optimistic


For a description, see Table 6-4


The following BMP entity bean parameters are not supported in this release.

max-instances, min-instances, pool-cache-timeout

Configuring Parameters for Session Beans

This section covers the parameters that are specified in the orion-ejb-jar.xml configuration file and apply for session beans.

Table 6-9 lists the stateless session bean specific parameters.

Table 6-10 lists the stateful session bean specific parameters.

Table 6-9  Stateless Session Bean Parameters
Parameter Description


For a description, see Table 6-4


The cache-timeout applies for Stateless Session EJBs. This parameter specifies how long to keep stateless sessions cached in the pool.

For stateless session beans, if you specify a cache-timeout, then at every cache-timeout interval, all beans in the pool, of the corresponding bean type, are removed. If the value specified is zero or negative, then the cache-timeout is disabled and beans are not removed from the pool.

Default Value: 60 (seconds)


For a description, see Table 6-4

Table 6-10  Stateful Session Bean Parameters
Parameter Description


For a description, see Table 6-4


The timeout applies for Stateful Session EJBs. If the value is zero or negative, then all timeouts are disabled.

The timeout parameter is an inactivity timeout for stateful session beans. Every 30 seconds the pool clean up logic is invoked. Within the pool clean up logic, only the sessions that timed out, by passing the timeout value, are deleted.

Adjust the timeout based on your applications use of stateful session beans. For example, if stateful session beans are not removed explicitly by your application, and the application creates many stateful session beans, then you may want to lower the timeout value.

If your application requires that a stateful session bean be available for longer than 30 minutes, then adjust the timeout value accordingly.

Default Value: 30 (minutes)


For a description, see Table 6-4

Using Multiple OC4Js and Limiting Connections

This section describes techniques that allow you to improve performance by setting the number of active processes within an OC4J Instance, sending applications to different OC4J Instances, and limiting the number of requests sent to an OC4J Instance.

This section covers the following topics:

Limiting HTTP Connections

You can improve J2EE application performance by limiting the number of active HTTP concurrent connections a given site accepts. Using Oracle HTTP Server with mod_oc4j, you can limit the number of incoming requests by setting the MaxClients parameter in httpd.conf.

See Also:

"Configuring Oracle HTTP Server Directives"

Limiting HTTP Connections with Standalone OC4J

If you are using standalone OC4J you can limit the number of active web users an OC4J site accepts concurrently by constraining the maximum allowable HTTP connections. Tuning parameters on a standalone OC4J can improve performance if there are a large number of concurrent users that the system cannot efficiently handle, or when there are limited resources which you cannot easily constrain.

To limit the HTTP connections, use the max-http-connections configuration element in server.xml and specify the attributes: value, max-connections-queue-timeout, and socket-backlog attributes.

For example, the following shows a line of server.xml that configures the maximum number of connections:

<max-http-connections max-connections-queue-timeout="120" socket-backlog="50" 

Table 6-11 describes the max-http-connections attributes.

When you want messages to be redirected to a different URL when the maximum connections limit is reached, include the HTTP redirect URL.

For example, to redirect to http://optional.redirect.url/page.jsp, add the following line to server.xml:

<max-http-connections max-connections-queue-timeout="120" socket-backlog="50" 

Table 6-11  Setting max-http-connections Attributes
Attribute Description


Specifies the number of seconds to wait for an available connection if the maximum connections have been reached before returning either server busy or redirect message.

Default Value: 10 (seconds)


Specifies the number of connections that can be queued up before denying connections at the socket level.

Default Value: 30


Specifies the maximum number of connections.

Default Value: 100000

See Also:

Appendix B, "Additional Information" in the Oracle9iAS Containers for J2EE User's Guide for information on the elements in OC4J server.xml file.

Configuring Multiple OC4J Processes

Oracle9iAS lets you configure multiple OC4J processes in an OC4J Instance. If there are sufficient resources on your system, you may be able to improve performance by configuring multiple OC4J processes for the OC4J Instance that services your J2EE application. Using multiple OC4J processes is the simplest form of load balancing without using Oracle9iAS clustering. Configuring an OC4J Instance to allow requests to be served by multiple OC4J processes can reduce or avoid contention and improve scalability. Oracle9iAS also supports multi node clustering for load balancing.

The optimal ratio of OC4J processes to CPUs is dependent on characteristics of the application, hardware configuration and JDK being used. But in general, for multi-cpu configurations with greater than two processors, you should consider configuring multiple OC4J processes. For example, on a recent test of a J2EE application, a single OC4J process was sufficient to use 70% of the resources on a four processor system. That statistic indicated that either adding a second OC4J process would be advantageous or that the incoming load was insufficient to utilize more of the machine resources. By monitoring the incoming load, we were able to determine that it was the former, and adding a second process improved performance.

Adding processes beyond the available resources of the system will not improve performance. For example, if one OC4J process is sufficient to saturate the CPU resources of a system, adding four more processes is not likely to improve performance and may, in fact, degrade it. A good starting point is to configure one OC4J process for every 2-3 CPUs and measure the improvement derived from adding additional processes.

Configuring Multiple OC4J Processes Using Oracle Enterprise Manager

Using Oracle Enterprise Manager you can specify the number of processes in an OC4J Instance using the OC4J Instance level configuration available on the OC4J Instance's home page.

If you configure your OC4J to use load-balancing with multiple OC4J processes running within the same island, and you do not want sessions to be replicated, make sure that the <distributable/> property is not set in the application's web.xml file.


Setting the <distributable/> property in web.xml can have significant performance overhead for applications that use sessions, since this configures the application to use session replication with failover when multiple OC4J processes are running within the same island.

See Also:

Chapter 3, "Advanced Configuration, Development, and Deployment", in Oracle9iAS Containers for J2EE User's Guide

Balancing Applications Across OC4J Instances

It is often beneficial to spread J2EE application load among multiple OC4J Instances, especially when applications are run on a multiprocessor system. Running multiple OC4J Instances generally results in higher throughput and shorter response time, even on a single-processor host.

If your web site has many different applications deployed which have different requirements and needs, you may want to configure different OC4J Instances, each with the appropriate number of OC4J processes to service the different applications.

To deploy applications to different OC4J Instances, perform the following steps:

  1. Create the multiple OC4J Instances.

  2. Using the Application Deployment Wizard, for each Instance, deploy the appropriate application to each instance, and specify a unique URL mapping for each of the applications.

After deploying the applications to different OC4J Instances, you can monitor the performance to see if throughput increases, or the response time decreases.

Database Monitoring and Tuning

To achieve optimal performance in Oracle9iAS OC4J J2EE applications that use the database, the database tables you access need to be designed with performance in mind, and you need to monitor and tune the database server to assure that the system is performant.

See Also:

Oracle9i Database Performance Tuning Guide and Reference

Improving BC4J Performance in Oracle9iAS

This section contains tips for improving the maintainability, scalability, and performance of your Oracle Business Components for Java (BC4J) applications.

See Also:

Developing Business Components under the heading Oracle9iAS Business Components for Java in the Oracle9iAS documentation library

Choose the Right Deployment Configuration

Your application will have the best performance and scalability if you deploy your business components to the web module with your client. Unless you have strong reasons (such as wanting to use distributed transactions or EJB security features), we recommend web module deployment of business components over EJB deployment.

Note that both web module deployment and EJB deployment are fully J2EE-compliant, and the BC4J framework makes it easy to switch between them. You can test your application in both modes to see which gives you the best performance.

Use Application Module Pooling for Scalability

A client can use application module instances from a pool, called application module pooling. This offers these advantages:

For example, in the case of a web application, you may have 1,000 users but you know that only 100 will be using a certain application module at one time. So you use an application module pool. When a client needs an application module instance, it takes a free one from the pool and releases it to the pool after either committing or rolling back the transaction. Because the instance is precreated, end users are saved the time it takes to instantiate the application module when they want to perform a task. Typically, web-based JSP clients use pools. If you want to make sure that the application module pool has a maximum of 100 application module instances, you can customize the default application module pool.

If your client needs to keep track of application module state, we recommend using stateful mode. In a stateful JSP application, the client does not reserve the application module instance, making it available to other clients if the number of application modules exceeds the recycle threshold. State is, instead, preserved in one of two ways: The application module pool returns a client's original application module if the application module has not been recycled, and the pool persists the state of recycled application modules in the database to be available to clients that request them later.

When you release an application module at the end of a user's session, be sure to use stateless (rather than stateful or reserved) release mode. This frees up database space and allows the pool to recycle the application module immediately.

Perform Global Framework Component Customization Using Custom Subclasses

Particularly in large organizations, you may want specific functionality shared by all components of a particular type--for example, by all view objects. An architect can create a thin layer of classes such as MyOrgViewObjectImpl that implement the desired behavior. Individual developers can extend MyOrgViewObjectImpl instead of ViewObjectImpl, and you can use the "substitutes" feature to extend MyOrgViewObjectImpl in legacy code.

Use SQL-Only and Forward-Only View Objects when Possible

Basing a view object on an entity object allows you to use the view object to insert, update, and delete data, and helps keep view objects based on the same data synchronized. However, if your view object is only going to be used for read-only queries, and there is no chance that the data being queried in this view object will have pending changes made through another view object in the same application module, you should use a SQL-only view object that has no underlying entities. This will give you improved performance, since rows do not need to be added to an entity cache.

If you are scrolling through data in one direction, such as formatting data for a web page, or for batch operations that proceed linearly, you can use a forward-only view object. Forward-only mode prevents data from entering the view cache. Using forward only mode can save memory resources and time, because only one view row is in memory at a time. Note that if the view object is based on one or more entity objects, the data does pass to the entity cache in the normal manner, but no rows are added to the view cache.

Do Not Let Your Application Modules Get Too Large

A root application module should correspond to one task--anything that you would include in a single database transaction. Do not put more view objects or view links than you will need for a particular task in a single application module.

In addition, consider deferring the creation of view links by creating them dynamically with createViewLink(). If you include all view links at design time, the business logic tier will automatically execute queries for all detail view objects when your client navigates through a master view object. Deferring view link creation will prevent the business logic tier from executing queries for detail view objects that you do not yet need.

For example, for a form in which detail rows are displayed only on request (rather than automatically), including a view link at design time would force the business logic tier to automatically execute a query that might well be unnecessary. To prevent this, you should create a view link dynamically when the detail rows are requested. By contrast, for a form in which detail rows are displayed as soon as a master is selected, you should use a view link created at design time to avoid the runtime overhead of calling createViewLink().

Use the Right Failover Mode

By default, the application module pool supports failover, which saves an application module's state to the database as soon as the application module is checked into the pool. If the business logic tier or the database becomes inoperable in mid-transaction (due to a power failure or system crash, for example), the client will be able to instantiate a new application module with the same state as the lost one, and no work will be lost.

However, some applications do not require this high level of reliability. If you're not worried about loss of work due to server problems, you may want to disable failover. When failover is disabled, the application module's state exists only in memory until it is committed to the database (at which point the application module's state is discarded) or recycled (at which point the state is saved so that the client can retrieve it). By not saving the application module state every time the application module is checked in, failover-disabled mode can improve performance.

Use View Row Spillover to Lower the Memory to Cache a Large Number of Rows

While the business logic tier is running, it stores view rows in a cache in memory (the Java heap). When the business logic tier needs to store many rows at once, you need to make sure it doesn't run out of memory. To do so, you can specify that when the number of rows reaches a certain size, the rows "overflow" to your database to be stored on disk. This feature is called view row spillover. If your application needs to work with a large query result, view row spillover can help the cache operate more efficiently.

Choose the Right Style of Bind Parameters

Oracle-style bind parameters (:1, :2, and so on) are more performant than JDBC-style bind parameters.

There are only two reasons to use JDBC-style bind parameters:

Implement Query Conditions at Design Time if Possible

You should include any portion of your query condition that you know in advance in the WHERE clause field in the View Object wizard. Only use setWhereClause() for genuinely dynamic query conditions.

Even if your query conditions are genuinely dynamic, you may be able to use parametrized queries instead of setWhereClause(). For example, if your view object needs to execute a query with the WHERE clause EMPLOYEE_ID=<x> for various values of x, use a parametrized WHERE clause such as EMPLOYEE_ID=:1. This is more efficient than repeatedly calling setWhereClause().

Use the Right JDBC Fetch Size

The default JDBC fetch size is optimized to provide the best tradeoff between memory usage and network usage for many applications. However, if network performance is a more serious concern than memory, consider raising the JDBC fetch size.

Turn off Event Listening in View Objects used in Batch Processes

In non-interactive, batch processes, there is no reason for view objects to listen for entity object events. Use ViewObject.setListenToEntityEvents(false) on such view objects to eliminate the performance overhead of event listening.

Go to previous page Go to next page
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Go To Product List
Solution Area
Go To Table Of Contents
Go To Index