Oracle® Application Server Performance Guide
10g Release 2 (10.1.2) B14001-02 |
|
Previous |
Next |
This chapter provides guidelines for improving the performance of Oracle Application Server Containers for J2EE (OC4J) applications in Oracle Application Server.
This chapter contains:
Improving J2EE Application Performance by Configuring OC4J Instance
Setting Java Command Line Options (Using JVM and OC4J Performance Options)
Improving Web Services Performance in Oracle Application Server
Improving JAAS (JAZN) Performance in Oracle Application Server
Using Multiple OC4Js, Limiting Connections and Load Balancing
Note: This chapter describes using Oracle Enterprise Manager 10g Application Server Control Console 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 10g Application Server Control Console for some Oracle Application Server configuration and management tasks.
|
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 |
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. |
Managing Concurrency and Limiting Connections |
|
Load Balancing |
|
Balancing Applications |
|
Database Monitoring and Tuning |
Tuning OC4J configuration options lets you 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:
Depending on your J2EE application, you may be able to improve the application's performance by setting Java Performance Options for the JVM running OC4J where your application is deployed.
This section covers the following topics:
Setting the JVM Permanent Generation Option for OC4J Processes
Using Application Server Control Console to Change JVM Command Line Options
When running Oracle Application Server, 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.
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 value. 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 256 Megabytes is advised. If you have sufficient memory, using a heap size of 512 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 Application Server Control Console to Change 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 512 megabytes, specify the following:
-Xms512m -Xmx512m
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 10g Application Server Control Console 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, after a timeout while attempting to make the change, Application Server Control Console reports an error, "An error occurred while restarting..." In this case, 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:
java.lang.OutOfMemoryError
Note: There are other reasonsjava.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, use the JVM metrics freeMemory
and totalMemory
. Subtracting the free memory from total memory gives the amount of heap that was consumed. To determine how much Java heap you need in a non-production environment, you can include calls in your program to the Runtime.getRuntime().totalMemory()
and Runtime.getRuntime().freeMemory
methods in the java.lang
package (including these calls in a production environment could have a negative performance impact).
See Also:
|
Oracle Application Server 10g uses the -server
option by default on UNIX systems (this is a change from previous Oracle9iAS releases). On UNIX systems, Java runs in one of two modes set with the options: -client
and -server
. If you need to change this option, use the procedures outlined in "Using Application Server Control Console to Change JVM Command Line Options", and specify the -client
Java option.
Oracle Application Server 10g uses the 1.4.2 version of the Java virtual machine (JVM). This JVM version includes an improved JIT compiler from previous JVM releases. Many long-running applications will perform better with the improved JIT. However, due to the increased quality of compilation, applications may experience slower program startup times or occasional pauses in other parts of a program (as compared with older versions of the JVM). In a multi-processor system, the compilation thread runs concurrently with OC4J startup, reducing the impact on startup time.
On UNIX systems, using the –server
option also changes the default heap allocation. For a given heap size, larger allocations are made to the Eden and Survivor generations at the expense of the Old generation. The Permanent generation is not affected. The memory footprint of the heap is not directly affected. See the following site for more details on heap sizes, generation names, and garbage collection,
http://developers.sun.com/techtopics/mobility/midp/articles/garbagecollection2/
In the 1.4.2 version of the Java virtual machine (JVM), the -XX:+AggressiveHeap
option was optimized for long-running, memory allocation-intensive applications. Many applications will exhibit dramatically improved performance and scalability if the -XX:+AggressiveHeap
option is specified. To set this option, use the procedures outlined in "Using Application Server Control Console to Change JVM Command Line Options".
See the following site for more details on using the -XX:+AggressiveHeap
option,
http://java.sun.com/j2se/1.4.2/1.4.2_whitepaper.html#6
Note: If you are running 32 bit Linux with kernel version 2.4.x on systems with large amounts of RAM, using the-XX:+AggressiveHeap option may cause the JVM to produce a startup error, "Could not reserve enough space for object heap". The 2.4.x Linux kernel limits the size of a single process to between 2 and 2.5 GB, depending on the kernel version. Use the JVM option -Xmx <heapSize> to keep the JVM process size under this limit. For example, set the -Xmx1800M option to avoid hitting the Linux process size limitation.
|
Depending on the particular J2EE application, changing the setting of the command line option -Xss
n for the JVM running OC4J may improve performance. To set this option, use the procedures outlined in "Using Application Server Control Console to Change JVM Command Line Options", and specify the -Xss
n Java option.
This option sets the maximum stack size for C code in a thread to the specified value 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:
-Xss128k
The MaxPermSize
option defines the size for the permanent generation in the JDK. Since the default value is 64M (Megabytes) in JDK 1.4.x, generally you do not need to change this value, which is used to hold reflective objects of the VM such as class objects and method objects. However, if your applications dynamically generate and load many classes that require a large permanent generation size, you may see outOfMemory
errors from the JDK even if you have plenty of free memory in the heap (we found this occurs in some JSP implementations). If this occurs, you can change the permanent generation size by setting the -XX:MaxPermSize
option, as follows:
-XX:MaxPermSize=sizem
Where size is the desired MaxPermSize
value.
You can disable the collection of most OC4J built-in performance metrics by setting a property for the JVM running OC4J. The default value for the property oracle.dms.sensors
is normal
, which enables the collection of built-in performance metrics. You can disable OC4J built-in performance metrics collection by setting the oracle.dms.sensors
property to the value none
. For most J2EE applications, using the default value, normal
, should have minimal impact on performance.
Note: Settingoracle.dms.sensors value to none causes Oracle Enterprise Manager 10g Application Server Control Console to report "unavailable" for some values that are based on metrics.
|
Table 6-2 lists the supported oracle.dms.sensors
property values.
Table 6-2 DMS Sensor oracle.dms.sensors Property Supported Values
Property Value | Description |
---|---|
|
Disable gathering of metrics. |
|
Enable normal level metric gathering. This is the default value. |
|
Enable heavy metric gathering. |
|
Enable all metrics. |
Some Oracle Application Server components that run in OC4J do not use the oracle.dms.sensors
property to control their metrics. For example, the Portal Servlet web.xml
specified configuration parameter dmsLogging
controls metric collection for the Portal PPE.
The JDBC drivers also do not use the oracle.dms.sensors
property to control certain JDBC metrics. To enable the collection of JDBC statement metrics, use the properties, oracle.jdbc.DMSStatementCachingMetrics
and oracle.jdbc.DMSStatementMetrics
.
See Also:
|
To improve performance, by default OC4J does not collect JDBC statement metrics. The properties, oracle.jdbc.DMSStatementCachingMetrics
and oracle.jdbc.DMSStatementMetrics
are by default, set to false
. When these properties are false
, performance is improved since OC4J does not collect expensive JDBC statement level metrics.
Setting these properties to true
may have a negative impact on performance. You should only set these properties to true
when you need to collect JDBC statement metrics.
When oracle.jdbc.DMSStatementCachingMetrics
property is set to true
and JDBC statement caching is enabled, the JDBC statement metrics are available.
When JDBC statement caching is disabled, make the JDBC statement metrics available by setting the property oracle.jdbc.DMSStatementMetrics
to true
.
Setting the dedicated RMI context property to false
, using the command line option -Ddedicated.rmicontext
= false
, in certain cases may improve performance for OC4J.
When you deploy an application containing EJB JAR files, OC4J automatically generates a wrapper class for each EJB that implements the various component interfaces packaged with the EJB application. OC4J then invokes the Java compiler to compile these generated EJB wrapper classes. OC4J supports two modes for compiling EJB wrapper classes: Batch mode and non-batch mode.
Batch mode is the default compilation mode for OC4J. In general, batch mode provides faster time to deployment when deploying large EJB-heavy applications. However, batch mode also requires a greater heap memory allocation than non-batch mode deployment. In batch mode, OC4J makes a single call to the Java compiler to compile all of the Java wrapper code for all of the EJBs within the EAR being deployed.
You can specify non-batch mode if you find that OC4J throws java.lang.OutOfMemory
exceptions while compiling in batch mode. If you encounter this exception, you may want to try selecting the non-batch mode, as it requires less memory allocation. However, using this mode can slow the deployment.
In non-batch mode, OC4J makes multiple calls to the compiler, one for each EJB JAR file within the EAR being deployed.
To deploy in non-batch mode, set the ejbdeploy.batch
system property to false
at OC4J startup using the command line option, -Dejbdeploy.batch=false
.
To change the command-line options for an OC4J instance, perform these steps:
Under the System Components table click and open the page for the OC4J instance on the Application Server Home page.
Click the Administration link on OC4J instance page.
Click Server Properties in the Instance Properties area on the Administration page.
Set Java Options in the Command Line Options area on the Server Properties page.
For example, enter the following in the Java Options field to set the JVM heap size to 512 Megabytes:
-Xmx512m
Click Apply to apply the changes.
Click Yes to restart the OC4J instance to restart the OC4J instance.
Figure 6-1 shows the Server Properties page with Java Options.
Figure 6-1 Application Server Control Console Java Heap Size Multiple VM Configuration Page
A data source enables you to retrieve a connection to a database server (a data source is an instantiation of an object that implements the javax.sql.DataSource
interface). 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:
Using the EJB Aware Location Specified in Emulated Data Sources
Setting the Cached Connection Inactivity Timeout in Data Sources
Setting the Wait for Free Connection Timeout in Data Sources
Setting the Maximum Number of Connection Attempts in Data Sources
Using Application Server Control to Change Data Source Configuration Options
Note: If your data source is provided by a third party, you may need to set certain properties. These properties should be defined in the third-party documentation. |
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 data sources and non-emulated data sources.
The pre-installed default data source is an emulated data source. Emulated data sources are wrappers around Oracle or non-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 emulated data sources to obtain connections to different databases by changing the values of the url
and connection-driver
parameters.
The following provides an example of a definition of an emulated data source:
<data-source class="com.evermind.sql.DriverManagerDataSource" name="OracleDS" location="jdbc/OracleCoreDS" xa-location="jdbc/xa/OracleXADS" ejb-location="jdbc/OracleDS" connection-driver="oracle.jdbc.driver.OracleDriver" username="scott" password="tiger" url="jdbc:oracle:thin:@localhost:5521:oracle" inactivity-timeout="30" />
Non-emulated data sources are pure Oracle data sources. You use non-emulated data sources for applications that need to coordinate access to multiple sessions within the same database or to multiple databases within a global transaction.
The ejb-location
only applies to 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. You can use this option for single phase commit transactions or emulated data sources.
The ejb-location
only applies to 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. 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.
Note: Oracle recommends that you only use theejb-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.
|
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-3 lists the values for the cacheScheme
property (DYNAMIC_SCHEME
is the default value for cacheScheme
).
Table 6-3 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.
|
The tradeoffs for changing the value of max-connections
are:
For some applications you can improve performance by limiting the number of connections to the database (this causes the system to queue requests in the mid-tier). For example, for one application that performed a combination of updates and complex parallel queries into the same database table, performance was improved by over 35% by reducing the maximum number of open connections to the database by limiting the value of max-connections
.
Note: You should check to make sure that your database is configured to allow at least the total number of open connections, as specified by the data sourcesmax-connections option for all your J2EE applications.
|
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.
Note: If themin-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. |
For emulated and non-emulated 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
.
For emulated and non-emulated 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:
Increase the allowable wait-timeout
.
Evaluate the application design for potential performance improvements.
Increase the system resources available and then adjust these parameters.
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.
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.
To lower the overhead of repeated cursor creation and repeated statement parsing and creation, you can use statement caching with database statements. To enable JDBC statement caching, which caches executable statements that are used repeatedly, configure a datasource to use statement caching. A JDBC statement cache is associated with a particular physical connection maintained by a datasource. A statement cache is not per datasource so it is not shared across all physical connections. The JDBC statement cache is maintained in the middle-tier (not in the database server).
You can dynamically enable and disable statement caching programmatically using the setStmtCacheSize()
method on the connection object.
To configure JDBC statement caching for a datasource, use the stmt-cache-size
attribute to set the size of the cache. This attribute sets the maximum number of statements to be placed in the cache. If you do not specify the stmt-cache-size
attribute or set it to zero, the statement cache is disabled.
The following XML sets the statement cache size to 200 statements.
<data-source> ... stmt-cache-size="200" </data-source>
To set the stmt-cache-size
attribute, first determine how many distinct statements the application issues to the database. Then, set the size of the cache to this number. If you do not know the number of statements that your application issues to the database, you can use the JDBC performance metrics to assist you with determining the statement cache size. To use the statement metrics you need to set the Java property oracle.jdbc.DMSStatementMetrics
to true
for the OC4J.
You can use the prefetch-size
parameter to change the data source behavior for a JDBC query from a CMP Entity bean. However, this parameter is configured in orion-ejb-jar.xml
rather than in data-sources.xml
.
Figure 6-2 shows the Oracle Enterprise Manager 10g Application Server Control Console configuration page that lets you view or modify a data source. To see this page in Application Server Control Console from an OC4J instance, do the following:
Under the System Components table click and open the page for the OC4J instance on the Application Server Home page.
Click the Administration link on the OC4J instance page.
Click Data Sources Under Application Defaults.
Select a data source and Click Edit (or you can select 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).
Application Server Control Console stores the data source elements that you add or modify in an XML file. This file defaults to the name data-sources.xml
, located in $ORACLE_HOME/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.
Figure 6-2 Application Server Control Console Data Sources Configuration Page
This section covers parameters that you can tune for OC4J performance in the server.xml
file for an OC4J instance.
This section covers the following topics:
Setting the OC4J Transaction Configuration Timeout in server.xml
Setting the OC4J Options for Stateful Session Bean Passivation in server.xml
Using Application Server Control Console to Change server.xml Configuration Options
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. This configuration parameter specifies the maximum time taken for a transaction to finish before it can get rolled back due to a timeout, and applies to all transactions on the OC4J instance.
By default server.xml
sets the transaction-config
to 30000 (30 seconds). You can change the transaction-config
timeout
value for applications that are getting transaction timeout errors, or if you know the transactions take longer than 30 seconds (including the time for waiting for connections set by wait-timeout
in datasources.xml
).
To change the transaction-config
timeout
value, change the following line in server.xml
. For example, the following line in server.xml
sets the transaction-config
timeout
parameter to 60 seconds:
<transaction-config timeout="60000"/>
Note: Thetransaction-confi g timeout is not an EJB specific timeout, but affects all transactions which use EJBs. However, the timeout specified with the transaction-config timeout value set in server.xml does not apply to MDB transactions.
|
The transaction-config
timeout
attribute applies for all transactions running in OC4J, and therefore must be big enough for your longest transaction (the transaction-config
timeout
applies for all transactions at the EJB level). Thus, set the transaction-config
timeout
attribute to a value greater than or equal to other transaction related attributes (for example the data sources wait-timeout
and the EJB call-timeout
).
The OC4J task manager is an OC4J background process that performs cleanup operations, including the task of timing out HttpSessions. The task manager runs at regular intervals. Using the taskmanager-granularity
attribute in server.xml
, you can manage when the task manager runs. This attribute sets how often the task manager performs its cleanup operations. The value specified is in milliseconds and the default value is 1000 milliseconds.
The default taskmanager-granularity
interval is usually adequate. If you modify the default value and set the value too high, such as to a value greater than 60000, one minute, this can delay the task of timing out of HttpSessions, which could lead to an OutOfMemory
error (if you use HttpSessions).
For example, the following entry in server.xml
sets taskmanager-granularity
to 60000 milliseconds (1 minute).
<application-server ... taskmanager-granularity="60000" ...>
Note: Changing thetaskmanager-granularity can affect the timing and accuracy for some of the EJB Entity and Session Bean parameters. See "EJB Timeouts Using a Non-default taskmanager-granularity" for complete details.
|
OC4J automatically performs passivation of stateful session beans unless you set the enable-passivation
attribute for the element <sfsb-config>
to false
. The default value for the attribute enable-passivation
is true
, which means that stateful session bean passivation occurs. If you have a situation where stateful session beans are not in a state to be passivated, set this attribute to false
.
OC4J contains a thread pooling mechanism for use in standalone OC4J. The OC4J server.xml
global thread pool attributes control the number of threads that OC4J uses. In an Oracle Application Server 10g environment, we recommend that you do not specify <global-thread-pool>
in server.xml
. You can use this parameter to control the number of threads when using standalone OC4J (that is, when you are not in an Oracle Application Server 10g environment).
Note: The default number of threads that OC4J can create is unbounded (except as limited by system resources). Thus, if you do not specify<global-thread-pool> in server.xml , the default behavior allows unbounded threads and threads are created on demand as needed.
|
To limit concurrency in an Oracle Application Server 10g environment, we recommend using the Oracle HTTP Server MaxClients
directive. When OC4J runs in an Oracle Application Server 10g environment, mod_oc4j
works with OC4J to control OC4J concurrency. In this environment, limiting the number of threads by specifying <global-thread-pool>
attributes in server.xml
can cause resource contention issues that may result in deadlocks.
To update and configure options in server.xml
using Application Server Control Console, first select the OC4J instance you want to modify. Then, select the Administration link and select the Advanced Properties link from the Instance Properties area. On the Advanced Server Properties page, select the server.xml
link. On the edit server.xml
page, select and modify the elements and attributes that you need to change. Finally, click Apply to apply the changes.
If you do not use Application Server Control Console, then edit server.xml
in the $ORACLE_HOME/j2ee/
instance_name/config
directory, and use the dcmctl
command to update the Oracle Application Server configuration as follows:
% dcmctl updateconfig -ct oc4j % dcmctl restart -ct oc4j
This section discusses configuration options and performance tips specific to servlets for optimizing OC4J performance.
This section covers the following topics:
This section covers the following:
By default, OC4J loads a servlet when the first request is made. OC4J also lets you 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.
Using the load-on-startup facility increases the start-up time for your OC4J process, but decreases first-request latency for servlets.
For example, add the <load-on-startup>
as follows:
<servlet> <servlet-name>viewsrc</servlet-name> <servlet-class>ViewSrc</servlet-class> <load-on-startup> </load-on-startup> </servlet>
Using Application Server Control Console you can specify that OC4J load an entire Web Module on startup:
On the OC4J instance home page, click the Administration lin.
In the Instance Properties area, click Website Properties.
To specify load on startup, on the Web site Properties page select checkbox under Load on startup from the URL Mappings for Web Modules table
This <expiration-setting>
element, that can be set in either global-web-application.xml
or orion-web.xml
sets the expiration for a given set of resources. This element can reduce the requests to the server by asking the browser to cache certain requests. If the Oracle Application Server instance uses OracleAS Web Cache, then this element is less useful, since Web Cache should serve such requests, when it is used. The <expiration-setting>
determines how long before resources expire in the browser. The browser reloads an expired resource upon the next request for it.
This option is useful for setting caching policies, such as for not reloading images as frequently as documents.
To set the <expiration-setting>
element, use the following attributes: expires
, url-pattern
.
expires
specifies the number of seconds before expiration, or when set to "never
" specifies no expiration. The default setting for expires
is "0" (zero), for immediate expiration.
url-pattern
specifies a URL pattern that the expiration applies to. For example, url-pattern="*.gif"
The default servlet session timeout for OC4J is 20 minutes. You can change this for a specific application by setting the <session-timeout>
parameter in the <session-config>
element of web.xml
. If this value is set too low, you may loose your saved session before getting the chance to reuse it. If this value is set too high, you may save too much session state and consume too much memory. The amount of memory used in each session depends on the size of the objects the application creates and puts into the sessions. Setting either a too small value, or a too large value for the session timeout can have an impact on performance.
The following tips can enable you to avoid or debug potential performance problems:
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.
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 Application Server Control Console, or by viewing the application's web module metrics.
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.
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
, sessionActivation.completed
and sessionActivation.active
.
JSPs by default create sessions. If you do not need to use sessions in your JSPs, turn them off.
The following example shows an application that creates sessions, but never uses them. In this example, we show metrics from a JSP under /oc4j/
application
/WEBs/
context
:
session.Activation.active: 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 this will cause memory or CPU consumption problems.
A well-tuned application shows sessionActivation.active
with a value that is less than sessionActivation.completed
before the session timeout. 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
:
session.Activation.active: 2 ops session.Activation.completed: 500 ops
The fact that two sessions are active and more than 500 have been created and completed indicates that sessions are being invalidated after use.
OC4J uses the class java.security.SecureRandom
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.
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:
Improving Performance by Altering JSP Configuration Parameters
Improving Performance by Tuning JSP Code
Note: A JSP is translated into a Java servlet before it runs, therefore servlet performance issues also apply for JSPs. |
Oracle Application Server 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:
The JESI tag library supports the use of Oracle Application Server Web Cache. This supports the use of the HTTP-level cache, maintained outside the application, that provides very fast cache operations. Oracle Application Server Web Cache is capable of caching static data, such HTML, GIF, or JPEG files, or dynamic data, such as servlet or JSP results.
The Web Object Cache tag library let you capture intermediate results of JSP and servlet execution, and subsequently reuse these cached results in other parts of the Java application logic.
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
.
This section covers the following topics:
See Also:
|
The main_mode
parameter determines whether classes are automatically reloaded or JSPs are automatically recompiled, in case of changes.
Table 6-1 shows the supported settings for main_mode
.
Table 6-4 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 Using this value can improve the performance of JSP applications. Note: before you set |
|
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 The dispatcher will check the timestamp of the JSP, retranslate it if it has been modified since loading, and execute all |
Note the following when working with the main_mode
parameter:
Because of the usage of in-memory values for class file last-modified times, removing a page implementation class file from the file system will not by itself cause retranslation of the associated JSP source.
The page implementation class file will be regenerated when the memory cache is lost. This happens whenever a request is directed to this page after the server is restarted or after another page in this application has been retranslated.
A page is not reloaded just because a statically included file has changed. Statically included files, included through <%@ include ... %>
syntax as opposed to <jsp:include ... />
syntax, are included during translation-time.
Note: Before you setmain_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.
|
Disabling or enabling the tag handler reuse to runtime or compile-time models can improve JSP performance when you specify that tag handler instances are to be reused within each JSP page. This is sometimes referred to as tag handler instance pooling. There are two models for this:
Runtime model: The logic and patterns of tag handler reuse is determined at runtime, during execution of the JSP pages. Tag handler reuse is within application scope.
Compile-time model: The logic and patterns of tag handler reuse is determined at compile-time, during translation of the JSP pages. Specifying this value is an effective way to improve performance for an application with very large numbers of tags within the same page (hundreds of tags, for example).
The JSP tags_reuse_default
configuration parameter lets you specify the reuse model.
The Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide includes information on additional configuration parameters that affect JSP performance, including the following:
check_page_scope
precompile_check
reduce_tag_code
static_text_in_chars
simple-jsp-mapping
enable-jsp-dispatcher-shortcut
This section describes changes you can make to your JSP code to improve performance.
This section covers the following topics:
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 objects the application creates and puts into the sessions. 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 20 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:
HttpSession session; session = httpRequest.getSession(true); . . . session.invalidate();
OC4J uses the class java.security.SecureRandom
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.
Note: JSP pages by default use sessions while servlets by default do not use sessions. |
See Also:
|
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> <P ALIGN=\"CENTER\"> <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(); %>
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" %>
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:
Static includes affect page size. Static includes avoid the overhead of the request dispatcher that a dynamic include necessitates, but may be problematic where large files are involved. Static includes are typically used to include small files whose content is used repeatedly in multiple JSPs. For example:
Statically include a logo or copyright message at the top or bottom of each page in your application.
Statically include a page with declarations or directives, such as imports of Java classes, that are required in multiple pages.
Statically include a central status checker
page from each page of your application.
Dynamic includes affect processing overhead and performance. Dynamic includes are useful for modular programming. You may have a page that sometimes executes on its own but sometimes is used to generate some of the output of other pages. Dynamically included pages can be reused in multiple including pages without increasing the size of the including pages.
Note: Both static includes and dynamic includes can be used only between pages in the same servlet context. |
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:
Put the static HTML into a separate file and use a dynamic include
command (jsp:include
) to include its output in the JSP output at runtime.
Note: A static<%@ include... %> command would not work. It would result in the included file being included at translation time, with its code being effectively copied back into the including page. This would not solve the problem.
|
Put the static HTML into a Java resource file.
The JSP translator will do this for you if you enable the external_resource
configuration parameter.
For pre-translation, the -extres
option of the ojspc
tool also offers this functionality.
Note: Putting static HTML into a resource file may result in a larger memory footprint than the precedingjsp:include workaround mentioned, because the page implementation class must load the resource file whenever the class is loaded.
|
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:
Table 6-5 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 (except MDBs).
Table 6-5 shows parameters that are specified in orion-ejb-jar.xml
.
This section also covers the following topic:
Table 6-5 EJB Parameters That Apply for All EJB Types (Except MDBs)
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. The container throws a Setting the Note 1: if you change the default value of the Note 2: When using transactions, set the Default Value: 90000 milliseconds See Also: "Setting the OC4J Transaction Configuration Timeout in server.xml" |
|
The number of bean instances allowed in memory – either instantiated or pooled. When this value is reached, the container attempts to passivate the oldest bean instance from memory (this passivation only applies for stateful session beans). If unsuccessful, the container waits the number of milliseconds set in the Set The exception, Default Value: 0 (unlimited) |
|
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 Default Value: 0 (for session beans and entity beans) See Also: "Setting the OC4J Transaction Configuration Timeout in server.xml" See Also: "Setting the Connection Retry Interval in Data Sources" |
|
The minimum number of bean implementation instances to be kept instantiated or pooled. These instances are created when an EJB of the specified type is accessed, when the first instance is requested, and not at OC4J startup. Default Value: 0 (instances) |
There are EJB administrative tasks that are run at an interval, the length of which depends on the taskmanager granularity. Therefore, if you change the default value of the taskmanager-granularity
attribute in server.xml
, this change also impacts the interval at which EJB administrative tasks are executed.
The taskmanager-granularity
specified interval affects EJB timeouts. EJB administrative tasks associated with timeouts depend on when the task manager runs, and a factor of 60 for EJB tasks. Thus, if the taskmanager-granularity
is changed from the default, the value specified for EJB timeouts will have a corresponding change in granularity.
This section covers parameters for entity beans using CMP. These parameters are specified in the orion-ejb-jar.xml
configuration file.
Table 6-6 lists the entity bean CMP specific parameters.
Table 6-7 describes the supported locking-mode
parameter values.
This section also covers the following CMP topics:
Table 6-6 CMP Entity Bean Performance Parameters
Parameter | Description |
---|---|
|
For a description, see "Setting the Batch Size Option to Batch UPDATE statements". |
|
For a description, see Table 6-5 |
This boolean parameter, when Default Value: |
|
If Default Value: |
|
This parameter is only used when The decision to set this value to Set to Default Value: |
|
Turns on lazy loading in the Default Value: |
|
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 See Table 6-8 for a description of Default Value: When omitted, use the database default setting |
|
Specifies lazy loading on the finder-method element. Specifying this value to Default Value: |
|
The locking modes, specified with the See Table 6-7 for a description of See Table 6-8 for a description of Default Value: |
|
|
See Table 6-5 |
See Table 6-5 |
|
|
See Table 6-5 |
This parameter specifies how long to keep CMP Entity Beans cached in the pool. If you specify a Note: if Note: if you change the default value of the Default Value: 60 (seconds) |
|
The Increasing the value for the It may be useful to increase the value from the default for finder-methods that fetch a lot of data, such as findAll on large tables, or custom finder-methods that retrieve many rows of data. You can see the affect of changing the The number of rows to prefetch can be set as desired using Default Value: 10 |
|
Specifies whether the container updates only modified fields or all fields to persistence storage for CMP entity beans when Default Value: |
|
The 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 If the EJB is generally not modified externally, so you're using |
Table 6-7 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 |
|
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 " |
|
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-8 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-8 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-8 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 (that is, 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
.
Using CMP Entity Beans, each finder method retrieves one or more objects. In the default scenario, with lazy-loading
set to false
, no lazy-loading, each finder method causes a single SQL select statement to be executed against the database. For a CMP bean, one or more objects are retrieved with all of their CMP fields. So, for example, if you implement an ejbFindAllEmployees
method, this finder retrieves all employee objects with all of the CMP fields in each employee object.
With lazy-loading
set to true
, only the primary keys of the objects retrieved within the finder are returned. Then, only when you access the object within your implementation, the OC4J container uploads the actual object based on the primary key. For example, with the ejbFindAllEmployees
finder method, when lazy-loading
is true
, all of the employee primary keys are returned in a Collection. Then, each time you access one of the employees in the Collection, OC4J uses the primary key to retrieve the single employee object from the database.
The lazy-loading
value should be set based on the performance considerations for your application. To determine whether lazy-loading
should be set to true
or false
, lazy-loading is on or off, consider the following guidelines:
If you use most of the retrieved objects, then you should set the lazy-loading
option to false
(use the default value).
If you set lazy-loading
to true
, the first time an object is accessed within a transaction another select statement is executed, which results in a round-trip between the container and the database. If you only access a limited set of the retrieved or found objects, or are doing a find only to verify existence, setting lazy-loading
to true
may improve performance.
You may want to enable lazy-loading
, set the value to true
, if the finder method returns many rows with lots of data. With large data sets where the finder method does not return quickly, it may be better to set lazy-loading
to true
, enable lazy loading, so that the finder method returns quickly. After this, the application accesses rows as needed and the initial finder method return wait time can be reduced, which can improve application performance.
To turn on lazy-loading in the findByPrimaryKey
method, set the findByPrimaryKey-lazy-loading
attribute to true
, as follows:
<entity-deployment ... findByPrimaryKey-lazy-loading="true" ... >
To turn on lazy-loading in any custom finder method, set the lazy-loading
attribute to true
in the <finder-method>
element for that custom finder, as follows:
<finder-method ... lazy-loading="true" ...> ... </finder-method>
OC4J can improve performance by sending UPDATE statements in a batch. This is beneficial when you have a lot of updates, more than 75% in the application. You can configure how many UPDATE statements to batch together to go out to the database in one round trip by setting the batch-size
element in entity-deployment
tag for your entity bean in the orion-ejb-jar.xml
. The default value for batch-size
is 1, with this value updates are not batched.
There is one exception to the use of batch-size
; if the application code requires execution of a SELECT statement within several UPDATE statements, the updates batched prior to the SELECT statement are executed against the database before executing the SELECT statement. This is done so that all updates are performed before you retrieve any data. If you know that it does not matter for this SELECT statement to be performed, then you can stop the automatic flushing by specifying delay-updates-until-commit
to true
for the bean.
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-9 lists the entity bean BMP specific parameters.
Table 6-9 BMP Entity Bean Performance Parameters and Descriptions
Parameter | Description |
---|---|
|
See Table 6-5 |
The locking modes, specified with the 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:
|
|
|
See Table 6-5 |
|
See Table 6-5 |
|
See Table 6-5 |
This parameter specifies how long to keep BMP Entity Beans cached in the pool. If you specify a Note: if Note: if you change the default value of the Default Value: 60 (seconds) |
This section covers the parameters that are specified in the orion-ejb-jar.xml
configuration file and apply for session beans.
Table 6-10 lists the stateless session bean specific parameters.
Table 6-11 lists the stateful session bean specific parameters.
This section also covers the following topic:
Table 6-10 Stateless Session Bean Parameters
Parameter | Description |
---|---|
|
See Table 6-5 |
This parameter specifies how long to keep stateless session EJBs cached in the pool. For stateless session EJBs, if you specify a Note: if Note: if you change the default value of the Default Value: 60 (seconds) |
|
See Table 6-5 |
|
|
See Table 6-5 |
|
See Table 6-5 Default Value: 0 (instances) |
Table 6-11 Stateful Session Bean Parameters
Parameter | Description |
---|---|
|
See Table 6-5 |
Specifies the idle timeout for each Session Bean. When the bean has been inactive for the specified Default Value: 300 (seconds). Note1: If the value specified for the Note2: if you change the default value of the To disable, specify "never" |
|
The number of bean instances allowed in memory. When this value is reached, the container attempts to passivate the oldest bean instance from memory. If unsuccessful, the container waits the number of milliseconds set in the To allow an unlimited number of bean instances, set Set See Table 6-5 |
|
Defines a threshold for how many active beans exist in relation to the The number of beans that are passivated after crossing this threshold is specified with the Default Value: 90% To disable, specify "never" |
|
|
Ssee Table 6-5 |
Defines a threshold for how much used JVM memory is allowed before passivation should occur. Specify an integer that is translated as a percentage. When the threshold is reached, beans are passivated, even if their idle timeout has not expired. The number of beans that are passivated after crossing this threshold is specified with the Default Value: 80% To disable, specify "never" |
|
This attribute is an integer that defines the number of beans to be passivated if any of the resource thresholds have been reached. Passivation of beans is performed using the least recently used algorithm. Default Value: one-third of the To disable |
|
The container checks all resources at this time interval. At this time, if any of the thresholds have been reached, passivation occurs. Default Value: 180 seconds (3 minutes). To disable, specify "never" |
|
Specifies the When a Stateful Session EJB is inactive, after the When the pool clean-up logic is invoked (by default every 30 seconds), the pool clean-up logic invalidates or removes the sessions that timed out, (sessions with expired Adjust the If your application requires that a Stateful Session EJBs be available for longer than 1800 seconds, 30 minutes, then adjust the Note 1: if you change the default value of the Note2: If the value specified for the Default Value: 1800 (seconds) |
Passivation for a Stateful Session Bean (SFSB) is invoked based on any combination of the following criteria:
The idle timeout expires for a bean instance. The idle timeout is specified with the idletime
parameter.
The container is determined to be out of resources, where a resource to be monitored is specified with the following parameters.
memory-threshold
max-instances-threshold
Note: If you use either of these parameters for container resource control, then setting theresource-check-interval , and passivate-count parameters is mandatory.
|
The number of bean instances allowed is reached as defined in the max-instances
parameter in the <session-deployment>
element in orion-ejb-jar.xml
(see Table 6-11 for details).
The OC4J instance terminates: the non passivated beans in memory are flushed to storage when the OC4J instance shuts down.
The attributes that control the Stateful Session Bean (SFSB) passivation management are configured in the <session-deployment>
tag of the orion-ejb-jar.xml
file for the deployed application.
Enabling passivation for the entire OC4J instance is configured at the container level in server.xml
using the <sfsb-config>
tag with the attribute enable-passivation
. When enable-passivation=false
this disables all the bean level settings for passivation and disables passivation at OC4J instance termination. When enable-passivation=true
applications can control bean passivation and passivation management using the passivation control parameters (see Table 6-11 for details).
Passivation is enabled by default and each stateful session bean is configured to passivate when any SFSB's idletime
expires, by default after 5 minutes, and when the OC4J instance terminates. By default, resource-based and max-instances based passivation is not enabled.
See Also:
|
The Stateful Session Bean (SFSB) activation and passivation model is analogous to using swap space at the operating system level – when certain operating characteristics are met, the in-memory state of qualified beans is flushed to disk, allowing more users to be served.
There is a performance overhead involved with passivation (which makes additional memory available). The overhead occurs when the state of the SFSB is written to disk, and when the SFSB is subsequently reused and the SFSB must be read from disk and activated. Therefore, if the configuration specified for the passivation parameters is "incorrect", this can cause significant passivation activity, and the "extra" passivation activity can degrade performance. Specifying passivation parameters with "incorrect" values can also use up disk space when a large amount of state is maintained in the SFSBs and when the beans are not expired (or do not expire for a very long time).
When your application is not affected by memory limitations, the best performance for SFSBs is achieved by disabling passivation completely, system wide, in server.xml
, or by setting parameters for each individual bean so that SFSB passivation is rarely used.
If the OC4J instance has passivation enabled, it will always passivate active beans in memory at shutdown.
To turn off all other kinds of passivation for individual beans, use the following parameters with the following values (see Table 6-11 for details):
idletime
=never
passivate-count=0
max-instances=0
max-instances-threshold=never
memory-threshold=never
resource-check-interval=never
When disabling passivation for an individual bean, note the following:
If you explicitly set passivate-count=0
, this also disables memory-threshold
and max-instances-threshold
.
If you explicitly set resource-check-interval=never
, this also disables memory-threshold
and max-instances-threshold.
You can passivate based on max-instances
with or without setting a max-instances-threshold
.
If you enable passivation to help control memory usage, you can improve performance by limiting the use of passivation (when possible). The following options are available to help control memory usage by SFSBs without requiring passivation:
Using Timeouts: specify the minimum timeout for the SFSB that your application requirements allow (using the timeout
attribute specified in orion-ejb-jar.xml
, see Table 6-11 for details). When a SFSB expires due to timeout, it is removed and not passivated (if it reaches timeout before the idletime timeout and before other passivation criteria are reached).
Using the remove()
method: if you know in the application when you are done using a particular SFSB, then you should call the bean remove()
method to release its memory rather than letting the bean timeout or be passivated.
The following are additional guidelines to help you decide if you need to use passivation:
Generally, if you do not reuse SFSBs quickly, then set the timeout
and the idletime
so the beans are removed without requiring passivation. To prevent passivation, set the timeout to be short and set the idletime
to a long time, or to never
, so that beans are not passivated before being removed (if you have sufficient memory to handle the load).
For example, consider an application where you create 1000's of SFSBs within 5 minutes, and you expect most of these beans to be idle for at least 5 minutes after first use and subsequently reused within 30 minutes. The default timeout is 30 minutes and the default idletime is 5 minutes. Then, in this case, it would be good to either increase the idletime
to 30 minutes or disable passivation based on idletime
. This guideline helps avoid having 1000's of SFSB passivated to disk, which has a costly performance overhead (the guideline also assumes you will not run into memory limitations by making this configuration change).
Consider setting max-instances
, idletime
, or memory resource thresholds to limit the number of beans in memory if:
You cannot fit all the SFSBs your client load generates and needs over a period of time (the timeout period of time) in memory.
You do want to save the state, since you know you will typically reuse it.
You cannot reduce the timeout for the SFSBs to reduce how many are saved.
You can look at the metrics for the methods create
, ejbPassivate
, ejbActivate
, and ejbRemove
on the SFSB to see how many stateful beans are created and how much passivation is occurring.
Set task-manager-granularity
to 1000 to get greater accuracy on tasks occurring near the timeout values for EJBs.
This section covers the EJB parameters specified in the orion-ejb-jar.xml
configuration file that apply for Message Driven Beans (MDBs).
Table 6-12 lists the MDB specific parameters.
See Also: "Java Message Service" in the Oracle Application Server Containers for J2EE Services Guide for information on using MDBs with OracleAS JMS and OJMS |
Table 6-12 Message Driven Bean orion-ejb-jar.xml Parameters
Parameter | Description |
---|---|
Specifies how many times the listener thread is to try to re-acquire the JMS session once a database failover has occurred. Setting the dequeue-retry-count can be useful when running with a RAC-enabled database cluster. Note: this parameter only applies to OJMS. Default Value: 0 |
|
Specifies how often the listener thread is to try to re-acquire the JMS session once a database failover has occurred. Setting the Note: this parameter only applies to OJMS. Default Value: |
|
If set to a value greater than 1, See Also: "Using The listener-threads MDB Parameter" for a detailed description of the Default Value: |
|
Specifies the maximum time taken for a transaction to finish before it is rolled back due to a timeout (this parameter only applies for an MDB that uses container-managed transactions). The MDB transaction timeout timer starts when the listener thread starts listening for a new message. Note: the
Default Value: 86,400 seconds (1 day) When using OracleAS JMS, the transaction timeout cannot be altered from the default value. |
Setting the listener-threads
parameter for an MDB can improve performance when there are many concurrent users sending messages to an MDB's queue, or when the processing that occurs in the onMessage
method is significant. For example, if the onMessage
method contains code to call another EJB and the EJB processing can occur concurrently while processing other messages, then specifying a listener-threads
value greater than one can improve performance. Depending on the underlying JMS provider and the specific MDB, some applications may see significant performance improvements by increasing the number of listener threads.
When the listener-threads
parameter is specified for an MDB, the OC4J runtime creates the specified number of threads to service messages for the MDB and specifies the degree of parallelism for the MDB. The listener threads are created when the MDB starts at OC4J startup.
For example, if a queue contains 100 messages, and the listener-threads
parameter is set to the default value, 1, then only one MDB listener-thread processes the messages, in a serial fashion. If the listener-threads
parameter is set to 5, there can be a maximum of 5 MDB instances that take messages from the queue, and process the messages in parallel. The total time required to complete the processing for 100 messages can be shortened since OC4J uses 5 MDB threads to dequeue and process the messages.
In a multiuser test, with 10 users, where listener-threads
is set to 5, compared to using the default value, 1, end-to-end performance improved by a factor of 2. This test involved a Servlet sending a message to an Oracle JMS queue, and then the MDB receiving the message from the queue and sending a reply to a reply queue.
In another test, using OracleAS JMS with listener-threads
set to 5, compared to the default value 1, throughput increased by 27%.
Note: Using thelistener-threads parameter, any performance improvement depends on the application and on the number of threads specified. Specifying a value that is too large may cause performance to degrade due to resource contention.
|
Notes for using listener-threads
:
The number of listener-threads
is included in the total global thread pool thread count specified using the max
thread pool parameter. Consider that the listener-threads
number of threads will be dedicated to MDB processing; therefore, you need to allocate this number, plus sufficient additional threads in the global thread pool to handle other OC4J processing.
When using OJMS, the number of listener-threads
is also the number of dedicated database connections that the MDB uses. So, the number of listener-threads
must be included in the total datasource specified max-connections
count.
The listener-threads
parameter is not supported for topics. Thus, topics can have at most one thread processing in an MDB.
Using listener-threads
with a value greater than 1, messages are still removed from a queue serially, but the order of processing the messages cannot be guaranteed since the MDB is processing the messages with multiple threads. Use listener-threads=1
, the default value, when the order of message processing is important. This assumes that the MDB is solely responsible for receiving messages from the queue.
When MDBs use OracleAS JMS as a message provider, DMS message related metrics are available from the Oracle Application Server performance monitoring tools.For example, the OracleAS JMS JMSStoreStats
metric table includes information for a destination corresponding to a queue that an MDB uses:
destination.value: name messageDequeued.count: x ops messageEnqueued.count: x ops messageCount.value: n
These metrics show the destination name, the total messages enqueued, the total number of messages dequeued, and the total number currently in the queue.
Note: When monitoring a JMS destination, other applications besides the MDB may access the destination. Thus, when testing your application's performance using the metrics, make sure that you know whether your application is responsible for message activity reported in the metrics. |
An MDB is stateless and contains no specific client state across invocations. However, for non-client related state, an MDB instance can contain some state across the handling of client messages. For example, state can be maintained for a JMS API connection object. In addition, other state information that you may want to cache across onMessage
invocations, such as a reference to an EJB, can be initialized in ejbCreate
method and cached to optimize MDB performance. Depending on the application and the message provider, you may be able to improve performance by selecting when JMS connections, JMS sessions, and other objects are initialized, either in the MDB ejbCreate
method or in onMessage
.
Table 6-13 summarizes some performance recommendations for selecting when to create JMS connections and JMS sessions using OracleAS JMS and Oracle JMS (OJMS).
Table 6-13 JMS Performance Recommendations With ejbCreate and onMessage
JMS Provider | Performance Recommendation |
---|---|
OracleAS JMS |
To optimize performance initialize the JMS connection and session once in the MDBs |
Oracle JMS |
You cannot cache JMS sessions to the database across |
In Oracle Application Server, the tuning guidelines for J2EE applications in general apply to Web Services. Specifically, because Web Services use Java Servlets for entry points, the guidelines for improving Servlet Performance apply to Oracle Application Server Web Services. In addition, when a Web Service is implemented as an EJB, the performance guidelines for EJBs apply.
This section covers the following topics:
Oracle Application Server Web Services may experience an initial request delay due to the work required to validate data types and to generate server skeleton code. As a result, the initial Web Service request takes substantially longer than subsequent requests. In our tests, we see the first test taking 5 to 10 times as long as subsequent requests. The delay is increased when Java Beans are used to represent complex parameter and result sets.
To prevent this delay, send a request to Web Services on the system when the system is restarted or when the application is redeployed. You can also produce a script to send the initial Web Service request.
There is a performance overhead associated with using Web Services untyped requests. When possible, develop clients that use typed requests as un-typed requests will take more time on the first request when the SOAP Mapping registry is created for the operation types.
See Also: Chapter 12, "Advanced Topics for Web Services" in the Oracle Application Server Web Services Developer's Guide for more information. |
When using Stateful Session based Web Services, tuning the session-timeout
property for session-scoped stateful applications can provide performance benefits. The HTTP session timeout is specified in the web.xml
configuration file as the <session-timeout>
sub-element of the <session-config>
element.
See Also: Chapter 2, "Servlet Development" in Oracle Application Server Containers for J2EE Servlet Developer's Guide |
This section contains tips for improving the maintainability, scalability, and performance of your Oracle Application Development Framework (ADF) applications.
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 ADF framework makes it easy to switch between them. You can test your application in both modes to see which gives you the best performance.
A client can use application module instances from a pool, called application module pooling. This offers these advantages:
It reduces the amount of time to obtain server-side resources
It allows a small number of instances to serve a much larger number of requests
It addresses the requirements of web applications that must handle thousands of incoming requests
It lets you preserve session state and provides failover support
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.
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.
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.
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()
.
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 malfunction, 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.
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.
Oracle-style bind parameters (:1, :2, and so on) are more performant than JDBC-style bind parameters.
Only use JDBC-style bind parameters if you may use a non-oracle JDBC driver.
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()
.
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.
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.
The Java Authentication and Authorization Service (JAAS) is a package that supports user and role-based authorization, authentication, and delegation. Part of JAAS is an implementation of the standard Pluggable Authentication Module (PAM) framework in Java, which supports the separation of an application from its underlying authentication technologies. Oracle Application Server provides an integrated JAAS implementation with OC4J called JAZN and provides a login module, out of the box, that supports several common forms of authentication.
When performing authentication and authorization operations, JAZN accesses a repository of data that defines users, roles, permissions, and related information. The characteristics of the repository are important to the performance and scalability of applications that use JAZN.
Oracle Application Server JAZN provides two types of repository provider for use with OC4J:
XML provider – The XML provider stores repository information in an XML file
LDAP provider – The LDAP provider stores repository information in the Oracle Internet Directory, which is accessed using the Lightweight Directory Access Protocol (LDAP)
This section covers the following topics:
When OC4J with JAZN is configured to use the XML provider, JAZN loads the entire XML file into a data structure in memory for fast access. In terms of performance, this process incurs a small start-up cost, but if the file is not too large and the data in the file can be retained in physical memory, data access will be very efficient and JAZN operations should incur little overhead.
When OC4J applications using JAZN are configured to use an LDAP provider, the LDAP repository is queried for data on demand. In this case, a single operation may involve multiple accesses to a remote directory, and the overhead for JAZN protection can become significant. Such overhead can be even greater if secure communications are required between OC4J and the repository which typically requires using SSL. When JAZN is configured to communicate with the LDAP repository using SSL, the performance issues of the SSL protocol should be considered.
There are several configuration choices to make when you set up SSL between OC4J, and LDAP (Oracle Internet Directory). SSL can be configured to use encryption only, or encryption plus client or server authentication.
To alleviate the costs of communicating with an LDAP repository, OC4J JAZN provides caches, including the following three separate caches:
The Policy Cache: stores grantees and permissions
The Realm Cache: stores realms, users and roles
Session cache: stores users and roles in an HTTP session object
The JAZN-LDAP caches are implemented as a single, in-memory hashtable. Objects in the cache are expired based on a configurable timeout value. A daemon thread runs periodically, at the timeout interval, to clean up expired objects in the cache. Each of the three caches can be enabled or disabled, and the initial capacity, load factor, initial cache purge delay, and cache purge timeout value can all be specified.
By default, the JAZN LDAP Provider is configured to use caching. Caching greatly improves the efficiency of using JAZN with an LDAP-based repository. Our experiments have shown the default values of cache configuration often work well, but you may need to test these values to determine how your application performs using JAZN.
Oracle Application Server OC4J provides an integrated JAAS implementation with OC4J. To configure the JAAS provider, you use jazn.xml
to determine if the provider is LDAP-based, uses Oracle Internet Directory as the data store, or XML based.
The file jazn.xml
is the configuration file for both the XML-based and LDAP-based JAAS providers. The JAAS Provider must locate a valid jazn.xml
file before it can begin running.When the JAAS provider starts up, it searches for jazn.xml
in order through the directories specified by:
oracle.security.jazn.config
(system property)
java.security.auth.policy
(system property)
$J2EE_HOME/config
($J2EE_HOME
is specified by the system property oracle.j2ee.home
)
$ORACLE_HOME/j2ee/home/config
($ORACLE_HOME
is specified by the system property oracle.home
)
. ./config
The JAAS provider stops searching after locating a jazn.xml
file. If no file is found, you receive the error message "JAZN has not been properly configured."
You can also use the <jazn>
tag to configure the JAAS Provider. The <jazn>
tag can appear in any of the following locations:
The application's orion-application.xml
The global application.xml
jazn.xml
The JAZN session cache can only be used by HTTP clients that have cookies enabled. Objects in this cache are held for the duration of an HTTP session. The HTTP session timeout is specified in the web.xml
configuration file as the <session-timeout>
sub-element <session-config>
element.
The following recommendations should help you to meet the performance requirements for applications that use JAZN for authentication and authorization:
If the JAZN XML file-based repository is sufficient for your needs, it is likely to provide the best performance.
If an LDAP repository is required, for management, usability, or scalability reasons, use the JAZN-LDAP caches. Configure the cache parameters as needed to improve performance.
If an LDAP repository is required, and if secure communications are needed between the LDAP repository and OC4J, configure the system to use only the level of security required. For example, use encryption only if that is sufficient.
For information on Oracle Application Server Toplink performance tuning, refer to the chapter, "Tuning for Performance", in the Oracle Application Server TopLink Application Developer's Guide.
This section outlines areas that allow you to improve performance by setting the number of processes in an OC4J instance, by directing requests to different OC4J instances, and by limiting the number of requests sent to an OC4J instance. These techniques spread the J2EE application load and the incoming requests among multiple OC4J processes which generally results in higher throughput and shorter response time. In addition, multiple OC4J processes are needed for load-balancing, high availability, and failover.
This section provides links to other Oracle Application Server documents and sections in this guide that show you how to configure and use multiple OC4Js.
Note: The replication features that provide for failover with Web sessions and for stateful session EJBs have a performance overhead; only use these features when failover features are needed. |
This section covers the following topics:
This section covers the following:
Oracle Application Server supports different types of installations and configurations, where you can run multiple OC4Js, including the following:
A standalone Oracle Application Server Instance with multiple OC4J instances (each OC4J instance may include multiple OC4J processes).
Oracle Application Server Clusters, managed, where a collection of application server instances runs with identical configurations and application deployments.
Oracle Application Server Clusters, non-managed, where the administrator manually configures each instance within a cluster.
A single or multiple hosts running standalone OC4J.
Determining the optimal ratio of OC4J processes to available CPUs is dependent on the characteristics of the applications you run, the OC4J configuration, the hardware configuration, and the type and number of expected incoming requests. 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 most of the CPU resources on a 2 processor system. Adding additional OC4J processes will not help improve performance on this system. However, on a six processor system, a single OC4J process uses only 70% of the CPU resources. Since additional CPU resources are available on this system, adding a second OC4J process should improve 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 additional 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 3-4 CPUs and measure the improvement from adding additional processes.
If your Oracle Application Server has many different applications deployed, each of which has different requirements, you may want to configure different OC4J instances to service the different applications (and OC4J instances may be configured with different numbers of OC4J processes).
To deploy applications to different OC4J instances, perform the following steps:
Create the multiple OC4J instances.
Use the Deploy Application Wizard, by click Deploy Ear File, on each instance, and deploy the appropriate application 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 overall throughput increases, or the response time decreases.
Using Application Server Control Console you can specify the number of processes in an OC4J instance from the Server Properties page. This page is available by selecting the Administration link from an OC4J Instance page.
OC4J provides load-balancing features for web-based applications with HTTP clients and for EJB applications accessed by remote Java EJB clients.
This section covers the following topics:
In an Oracle Application Server environment, the Oracle HTTP Server uses mod_oc4j
to load balance requests between the available OC4J processes. In this environment you can select mod_oc4
j configuration options to choose the appropriate mod_oc4j
load balancing policies to improve performance.
After an EJB application is deployed to multiple OC4Js, an EJB client-side application can load balance its requests across the available OC4Js. To use load balancing, the client-side application configures the JNDI properties to use load balancing.
There are three ways that the EJB client-side application can set the JNDI properties, including:
Setting the properties in the environment passed to the InitialContext
Setting the properties in the jndi.properties
file
Setting the JVM system parameters on the client-side OC4J
This section shows the EJB client-side properties that are specified in the jndi.properties
file. This section shows the load balancing related properties, but does not include all the available properties.
See Also:
|
The java.naming.factory.initial
property specifies the initial context factory to use.
Oracle Process Manager and Notification Server (OPMN) dynamically sets all ports, including the RMI port, when each OC4J instance starts.
Using the java.naming.provider.url
property in the EJB client-side JNDI properties, the client-side OC4J retrieves a list of the available dynamic ports for the OC4J instance, and if the OC4J instance is part of a cluster, a list of all the available dynamic ports for that instance across the cluster. If the list includes more than one port, the EJB client-side code randomly picks one port from the list to send your requests to. All EJB lookups using that InitalContext will go to the selected host.
Use the following syntax for setting the URL, including the opmn:ormi:
prefix for the java.naming.provider.url
property:
opmn:ormi://opmn_host
:opmn_por
t:oc4j_instance
/application-name
The OPMN host name, opmn_host
, and port number, opmn_port
, is retrieved from the $ORACLE_HOME/opmn/conf/opmn.xm
l file.
In most cases, OPMN is located on the same machine as the OC4J instance. However, you must specify the host name in case it is located on another machine. The OPMN port number is optional; if excluded, the default is port 6003. The OPMN port is specified in the file $ORACLE_HOME/opmn/conf/opmn.xml
.
For standalone OC4J, specify the java.naming.url
property using a comma separated list of URLs including the ormi:
prefix and the hosts where OC4J runs. This load-balances EJB client get InitialContext requests randomly across the hosts and OC4J processes specified in the comma separated list. All EJB lookups using that InitalContext will go to the selected host.
The syntax for specifying each URL for a host is as follows:
ormi://hostname
:ormi_por
t/application-name
The ORMI port, ormi_port
, can be omitted if the port is the default ORMI port number (23791).
For example, to load balance to my_ejb_app
that is running on host1, host2, and host3, set the property java.naming.provider.url
as follows:
java.naming.provider.url=ormi://host1:23791/my_ejb_app,ormi://host2:23792/my_ejb_app,ormi://host3:23791/my_ejb_app
Setting the java.naming.security.principal
property specifies the username.
Setting the java.naming.security.credentials
property specifies the password.
When you set the property dedicated.rmicontext=true
, then each initial context lookup receives its own InitialContext instead of a shared context. This option is only needed if an EJB client is doing multiple initial context lookups within the same JVM and you want to use load balancing.
When the property dedicated.rmicontext
is false
, OC4J load balances only on the first get initial context call. This dedicated.rmicontext
property is set to false
by default.
This section covers the following topics:
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
.
To limit remote EJB client connections, you can use the global thread pool features that control the maximum number of threads that service incoming EJB clients. By configuring the <global-thread-pool>
in server.xml
to use two thread pools, you can set the parameter cx-max
to limit remote EJB client connections.
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
. The default value
is 1000000, the default max-connections-queue-timeout
is 10 seconds, and the default socket-backlog
is 30.
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" value="100"/>
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://example.com/page.jsp
, add the following line to server.xml
:
<max-http-connections max-connections-queue-timeout="120" socket-backlog="50" value="100"> http://example.com/page.jsp </max-http-connections>
See Also: Appendix A, "Additional Information" in the Oracle Application Server Containers for J2EE User's Guide for information on<max-http-connections> attributes
|
This section covers the following:
The replication features that provide for failover with Web sessions have a performance overhead. You should only use these features when their use is a requirement for the application or for the production environment.
You can disable replication for all applications running on OC4J using Application Server Control Console. From the OC4J Instance page select the Administration Link. Then, select the Replication Properties Link. On the Replication Properties page, deselecting the Replicate session state checkbox turns off Web replication for the OC4J instance. This removes the <cluster-config>
element from global-web-application.xml
and disables OC4J Web replication for all applications running on the OC4J instance.
If you do not want sessions to be replicated in a particular application, then remove the <distributable/>
element from the application's web.xml
file. This disables replication for the application even if OC4J has enabled replication.With replication enabled, setting the <distributable/>
element in web.xml
can have significant performance overhead for applications that use sessions, since this configures the application to use session replication.
Many factors have an impact on the time it takes to deploy J2EE Applications on OC4J running in an Oracle Application Server environment.
This section covers the following:
Deployment Performance During the Application Development Phase
Deployment Performance During the Test and Production Phases
The following development phase choices have an impact on application deployment time for applications that are deployed to OC4J.
JVM flags – The JVM –server
flag is recommended for production use and is the default for OC4J when running in an Oracle Application Server environment. We have found –server
usually improves performance in server environments. However, using the –server
option increases the time required to restart a JVM and can require more memory.
Heap requirements – When you deploy large applications, if the deployment triggers JVM garbage collection, you may improve performance by increasing the size of the heap. Increasing the heap may provide enough memory so that the garbage collection is avoided. To increase the size of the heap, use either the –Xmx
JVM option or set the -XX:+AggressiveHeap
option. In addition, if the system is constrained for physical memory you may wish to shut down unused OC4J instances to reclaim physical memory.
Application Type – EJB applications require a compilation phase during deployment, and typically take longer to deploy than other type of J2EE applications.
Browser type – The default configuration of Internet Explorer uses a buffer size of 8K. This size limitation can cause a delay in transmitting large files which can result in a significant performance degradation on deployments of large applications. We advise changing the configuration option to increase the buffer size. For detailed instructions on changing the buffer size, see the following site,
http://support.microsoft.com/default.aspx?scid=kb;en-us;329781
This issue is also present with Netscape 7.0 and Mozilla 1.0.2., however we are not aware of any workarounds. If you are using these browsers, you may decide to use a different browser or manually copy the .ear
file to the local host and deploy using a command line tools (admin.jar
or dcmctl
). Netscape versions 4.79 and 7.1 do not exhibit this problem.
File system utilization – Deploying applications involves file I/O to the local deployment directory. File I/O speeds may be impacted by the percentage utilization of the file system. Consult your platform documentation for recommendations about optimal utilization levels. However, many platform vendors recommend maintaining file system utilization below 90% for optimal performance.
Batch Mode or Non-Batch Mode – EJB applications require a compilation phase during deployment, and typically take longer to deploy than other types of J2EE applications. You can specify non-batch mode if you find that OC4J throws java.lang.OutOfMemory
exceptions while compiling in batch mode (the default). If you encounter this exception, you may want to try selecting non-batch mode, as it requires less memory allocation. However, using this mode can slow the deployment.
The following test or production phase choices have an impact on the time it takes to deploy an application to OC4J.
Deployment Tool – For production use with Oracle Application Server, you must deploy applications using either: dcmctl
, Application Server Control Console, or JDeveloper. If you use dcmctl
to deploy applications and need to perform multiple deploys or management commands, using the dcmctl
shell mode provides a minor performance savings. Using the shell mode, the dcmctl
client maintains a single client process for all the commands you run.
Repository Type – If you are using an Oracle Application Server with a database repository, where the repository runs on a remote host, you may see slightly higher deployment times depending on the network latency at your site. Deploying to an Oracle Application Server with a local file-based repository usually is the most performant. Your choice of repository type should be driven by the availability and architectural requirements for your site and by application and deployment requirements.
Oracle HTTP Server Process State – As a final phase of application deployment, if the Oracle HTTP Server is running, OPMN issues a command to restart the Oracle HTTP Server. This action updates the routing information for the newly deployed application. If you have a number of applications to deploy, and you are not running in a live production environment, you may wish to leave the Oracle HTTP Server down until after all applications are deployed. This avoids repeated restarts for the Oracle HTTP Server. However, restarting the Oracle HTTP Server only takes a few seconds, depending on the system speed, so the performance savings is not dramatic unless you are deploying a large number of applications.
OC4J Process State – If the OC4J instance that you wish to deploy to is not started at the time the deploy command is issued, OPMN will start the instance and then shut it down when the deployment is complete. Again, these restart times are primarily significant when you are deploying multiple applications.
Heap requirements – When you deploy large applications, the deployment may trigger JVM garbage collection. In memory-constrained environments, where you cannot increase the size of the heap to provide enough memory so that the garbage collection is avoided, then, typically, the only result of a garbage collection is an increase in the application deployment time (and an increase in response times for requests to the OC4J instance or request timeouts). However, if the application being deployed is extremely large, the extended duration of the garbage collection may trigger OPMN to restart the OC4J instance.
To avoid OC4J restarts, increase the OPMN ping failure limit by setting values for the no-reverseping-failed-ping-limit
and reverseping-failed-ping-limit
parameters in opmn.xml
. For example, set these values as follows:
<category id="restart-parameters"> <data id="no-reverseping-failed-ping-limit" value="2"/> <data id="reverseping-failed-ping-limit" value="10"/> </category>
The default value for no-reverseping-failed-ping-limit
is 1 and the default value for reverseping-failed-ping-limit
is 3.
Batch Mode or Non-Batch Mode – EJB applications require a compilation phase during deployment, and typically take longer to deploy than other types of J2EE applications. You can specify non-batch mode if you find that OC4J throws java.lang.OutOfMemory
exceptions while compiling in batch mode (the default). If you encounter this exception, you may want to try selecting non-batch mode, as it requires less memory allocation. However, using this mode can slow the deployment.