September 23, 2004
Steve Anderson and Michael Gantman
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.
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.
Properties can be set in the following ways:
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.
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.
ADF BC supports two types of pooling, application module pooling and JDBC connection 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:
Using these numbers, you can properly set your pool size and control the timing of your pool.
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.
For more information on application module pool sizing issue please see Understanding Application Module Pooling Concepts and Configuration Parameters.
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.
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".
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 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 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.
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.
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.
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)