How to Performance Tune an ADF Business Components (ADF BC) Application
September 23, 2004
Steve Anderson and Michael Gantman
Abstract:
Oracle ADF Business Components provides sophisticated and powerful options
for maximizing the performance of applications written using the framework.
This article describes several of these tuning options and includes links to
other articles for more details on specific topics.
Oracle's Application Development Framework Business Components (ADF BC) are
a powerful way to develop J2EE datadriven applications. Along with that power,
comes the flexibility to configure your ADF BC application in many different
ways, allowing you to maximize the performance for the specific architecture
of your application.
This document is written for ADF BC and JDeveloper 10g. Although these techniques
may work with other releases, be aware that different version of Business Components
may have different configuration options. You can ensure that you are using
the newest libraries by using the ADF Runtime installer from within JDeveloper,
or by following the How
To Update ADF Runtime Libraries to Oracle Application Server 10g guide.
This document is written with a focus on applications deployed to Oracle iAS,
and some points within this documents are iAS specific. However, most of the
information is general and is applicable to any application server and all
versions of business components. For more details on ADF BC and other application
servers, please refer to Application
Servers Supported by JDeveloper.
Setting Business Components Configuration Property
Values
In JDeveloper, a Business Components project is configured by right clicking
on the application module and choosing "Configurations" from the
context menu. Any configuration values that are not equal to the default values
will be stored in the bc4j.xcfg file. Other options can be set in the client,
by the JVM, or in other configuration files. Because these options may be set
in multiple places, it is important to understand from where the properties
can be set, and the precedence of property values.
Business Components Property Values Precedence
Properties can be set in the following ways:
Client environment configuration settings in bc4j.xcfg
Client settings (for example, applet tags)
-D flags passed to the JVM
Business Components .properties file (in current directory, usually bc4j.properties)
System defined default (stored in Business Componentsmt.jar)
The lower the number, the higher the precedence.
For example, values in the bc4j.xcfg file override any options set via the
-D flag. In other words, if you want to use a -D option to set some global
defaults, you need to make sure that there is not an entry for that value in
the bc4j.xcfg file, otherwise the value in the bc4j.xcfg file will override
the -D option.
Being able to set configuration values in so many locations allows you very
fine grained control over them. For example, you may have a system wide policy
set for spillover. You can set that in the System defined default and all your
applications will use it. If you later find that have to override that system
wide setting for a particular application, you can put that setting in the
bc4j.xcfg file and be sure that all the other applications will not be affected.
Data Synchronization Mode
There are two modes for data synchronization in ADF BC - batch mode and immediate
mode. Batch mode is the default in JDeveloper 10g. Batch mode allows the client
to disconnect from the middle tier. This often, especially in applications
using rich clients like JClient, can result in significant performance gains
due to the decrease in network round trips. However, if your application has
a high level of interactivity with the database, you may need to use immediate
mode. Web applications often see a significant performance increase when they
use the correct data synchronization mode. For information on changing the
query data synchronization, see JDeveloper's online
help.
Pooling
ADF BC supports two types of pooling, application module pooling and JDBC
connection pooling.
Application Module Pooling
Application module pooling is an essential feature of a scalable ADF BC application,
because it allows a small number of application module instances to serve a
larger number of requests. This is an important scalability feature, and is
enabled by default. However, if you need to disable it, you can either set
the configuration parameter jbo.ampool.doampooling to false, or uncheck "Application
Pooling Enabled" in the configuration editor.
Application module pooling is highly configurable, and in order to implement
the best pooling strategy you need to know how your pools are being used. For
this reason the enterprise manager displays detailed information about each
application module pool, including:
Time taken to create each application module instance
Application module pool use (check outs, check ins, recycling statistics)
Maximum, average, and current pool size
Available and referenced instances
Length of time that instances remain idle
Number of application modules created and removed
Number of state activations and passivations
Number of sessions using the pool
JVM memory usage
Using these numbers, you can properly set your pool size and control the timing
of your pool.
Application Module Pool Sizing
There are five properties that govern the the application module poolsize, jbo.ampool.maxpoolsize,
jbo.ampool.maxavailablesize, jbo.ampool.minavailablesize, jbo.recyclethreshold,
and jbo.init.poolsize.
The maximum number of connections your application is allowed to make to
your data source is controlled by setting jbo.ampool.maxpoolsize. If your data
source has a maximum number of sessions allowed, jbo.ampool.maxpoolsize should
be lower than that maximum. If you know the maximum number of users you expect
in your application, or the maximum expected amount of application module instances,
then jbo.ampool.maxpoolsize should be set to that value. This can help you
avoid swamping your data source or application server if something goes wrong
in your application, helping you avoid unexpected errors.
The maximum number of application modules instances that could be kept idle
in the pool waiting for a request is controlled by setting jbo.ampool.maxavailablesize.
The minimum number of application module instances that will be kept idle
in the pool waiting for a request is controlled by setting jbo.ampool.minavailablesize.
Because creating a new application module instance is a costly performance
operation, you should use jbo.ampool.maxavailablesize and jbo.ampool.minavailablesize
to ensure that there are available application module instance in the pool
when they are needed. However, if you set these values too high, you
could be using resources that could be better used elsewhere. Note that you
can set both of these to the same value.
Each application will have different needs, so there are no rules for the
best values for these two settings. We do recommended that they should be set
to the expected number of concurrent pool requests, otherwise you will have
a high number of application module instance creations and/or removals. The
expected concurrent number of requests can be found by observing application
statistics using iAS Enterprise Manager. It should be the average number of
active requests, or the request processing time average multiplied by the number
of requests per second.
Keep in mind that if your application is deployed on several instances of
OC4J, or if it uses clustering, each instance of OC4J will have its own instance
of the pool, and the application module pool properties should be set accordingly.
For example, if you have a datasource that is limited to 100 users and you
deploy your application to two OC4J processes jbo.ampool.maxpoolsize parameter should
be no more then 50 (100/2).
Beyond the maximum and minimum pool size, you also want to set the reference
pool size. The reference pool size is the number of AM instances in the pool
that attempt to preserve session affinity for the next request made by the
session which used them last before releasing them to the pool in managed-state
mode. This is controlled by the parameter jbo.recyclethreshhold . An active
session is one which will be expected to send subsequent requests before timing
out. The number of active sessions at each moment can be seen using iAS Enterprise
Manager.
You should also set the initial application module poolsize (jbo.ampool.initpoolsize)
to be equal to the value for jbo.recyclethreshhold.
You can control how often the application module pool tests for inactive
application module instances by setting jbo.ampool.monitorsleepinterval, and you
can also control how long idle application module instances in the pool will
be kept before being garbage collected, by setting jbo.ampool.maxinactivage.
When there are more application module instances in the pool than jbo.ampool.maxavailablesize,
application module instances will be removed, after a length of time, in milliseconds,
as controlled by jbo.ampool.maxinactiveage. The default value is 600000ms,
which is 10 minutes. In many cases that is too long, and could be shortened
to make Application Module pooling more dynamic and self
adjustable. This parameter could be reduced to 5 or even 3
minutes or even shorter.
The period of time, in milliseconds, between checks for idle application
modules is controlled by jbo.ampool.monitorsleepinterval. We recommend setting
it to less then twice the value of jbo.ampool.maxinactiveage.
JDBC Connection Pooling
Most application servers typically do not do connection pooling when you are
not using JDBC data sources. If your application uses JDBC URL connections,
rather than JDBC data sources, ADF BC can provide JDBC connection pooling.
ADF BC JDBC connection pooling is disabled by default. ADF BC can also provide
JDBC connection pooling for data source connections if you prefer to use it
rather than using your application server's JDBC connection pooling.
The most common reason for using ADF BC connection pooling rather than your
application servers connection pooling is if an application has more than one
application module pool that is sharing connections from a single connection
pool/pooled data source. To understand the advantages and disadvantages of
this case please see Understanding
Application Module Pooling Concepts and Configuration Parameters.
If you want to enable JDBC connection pooling, you can do so either by
checking "Disconnect Application module upon release" in the configuration
editor, or by setting the configuration property jbo.doconnectionpooling to "true".
JDBC Data Sources
We recommended using JDBC data source connections, rather then JDBC URL connections.
Besides being the J2EE standard, datasources tend to be more secure (no login
information is included with the client), can be remapped to a different database
connection in the deployed environment, and make use of the container's connection
pooling. For more details on how to configure a data source connection
please see Using
JDBC Data Sources with ADF Business Components.
Dynamic JDBC credentials
Dynamic JDBC credentials are not enabled by default. You should not use dynamic
JDBC credentials unless they are needed. They increase network traffic between
your application and the database, and thus will decrease application performance.
See How
to Support Dynamic JDBC Credentials for instances examples of when JDBC
credentials may be needed, and information on how to use them.
Spillover
Spillover is used when the container runs out of memory in JVM and "spills
over" into the datasource, using a database table as virtual memory. This
results in a heavy performance penalty and should be used only as a last resort.
See Overview
of Temporary Tables Created By BC4J for more information on when you
may need to use spillover.
By default, in JDeveloper 10g, the spillover feature (jbo.use.pers.coll) is
disabled. However, if you have a project created in an earlier version of JDeveloper,
it may not be set to false.
Failover
When using failover, if, for whatever reason, an application module instance
gets lost, its state is always saved, and may be activated by any application
module instance at any time. This capability comes at expense of the
additional overhead of performing passivation every time an application module
is checked back into the pool. The failover option is a classic case of performance
versus reliability trade off.
There is no clear-cut recommendation on the value of this parameter and you
will have to make the decision whether to use failover or not based on the
resources available and the nature of your application. The default setting
of the failover mode is true, meaning that out of the box ADF BC opts to err
on the side of reliability, rather than performance in this area.
Failover is controlled by jbo.dofailover. Setting this to off will disable
failover. Setting it to on will enable failover.
Data Source Failover
The ADF BC application pool implements an active database ping upon AM use
boundaries to ensure that the AM connection is alive before handing the AM
reference to the application. If the AM connection is dead, then the application
pool will reconnect the AM on behalf of the application while retaining the
AM state.
Some modern JDBC data source implementations, including Oracle's, now provide
transparent application failover for connections; this support makes this data
source failover in ADF BC unnecessary. In addition, some applications may not
want to sacrifice the performance of the database ping for the level of quality
that is provided. The active ping may be disabled for applications with these
requirements by defining the property jbo.connectfailover=false.
Applications that have disabled connect failover and are not using another
transparent failover mechanism may encounter infrequent connection exceptions.
It is expected that these exceptions will not prevent further operation of
the middle tier and should be limited in scope to the session that has requested
the AM with the failed connection.
Number of Java Virtual Machines in a Web environment
When deploying ADF BC in a web environment, you will usually get the best
performance with ADF BC and the web client (JSP, for example) running in the
same Java virtual machine (JVM)