Oracle9i Application Server Performance Guide Release 2 (9.0.2) Part Number A95102-02 |
|
This chapter provides guidelines for improving the performance of Oracle9iAS Containers for J2EE (OC4J) applications in Oracle9i Application Server.
This chapter contains:
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.
Tuning OC4J configuration options allows you to improve the performance of J2EE applications running on an OC4J Instance. Modifying the configuration may require balancing the available resources on your system with the performance requirements for your applications.
This section covers configuration changes that can affect J2EE application performance and includes the following topics:
When running Oracle9iAS, the module mod_oc4j
is the connector from Oracle HTTP Server to one or more OC4J Instances. Each OC4J process within an OC4J Instance runs in its own Java Virtual Machine (JVM) and is responsible for parsing J2EE requests and generating a response. When a request comes into Oracle HTTP Server, mod_oc4j
picks an OC4J process and routes the request to the selected OC4J process. Within each OC4J Instance all of the OC4J JVM processes use the same configuration and start with the same Java options. Likewise, unless a process dies or there is some other problem, each OC4J process that is part of an OC4J Instance has the same J2EE applications deployed to it.
Depending on your J2EE application, you may be able to improve the application's performance by setting Java Options for the JVM running OC4J where your application is deployed.
If you have sufficient memory available on your system and your application is memory intensive, you can improve your application performance by increasing the JVM heap size from the default values. While the amount of heap size required varies based on the application and on the amount of memory available, for most OC4J server applications, a heap size of at least 128 Megabytes is advised. If you have sufficient memory, using a heap size of 256 Megabytes or larger is preferable.
To change the size of the heap allocated to the OC4J processes in an OC4J Instance, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the following Java options:
-Xmssizem -Xmxsizem
Where size is the desired Java heap size in megabytes.
If you know that your application will consistently require a larger amount of heap, you can improve performance by setting the minimum heap size equal to the maximum heap size, by setting the JVM -Xms
size to be the same as the -Xmx
size.
For example, to specify a heap size of 128 megabytes, specify the following:
-Xms128m -Xmx128m
You should set your maximum Java heap size so that the total memory consumed by all of the JVMs running on the system does not exceed the memory capacity of your system. If you select a value for the Java heap size that is too large for your hardware configuration, one or more of the OC4J processes within the OC4J Instance may not start, and Oracle Enterprise Manager reports an error. Review the log files for the OC4J Instance in the directory $ORACLE_HOME/opmn/logs
, to find the error report:
Could not reserve enough space for object heap Error occurred during initialization of VM
If you select a value for the JVM heap size that is too small, none of the OC4J processes will be able to start, and Oracle Enterprise Manager reports an error. If you review the log files for the OC4J Instance in the directory $ORACLE_HOME/opmn/logs
, you may find errors similar to the following:
java.lang.OutOfMemoryError
If the system runs out of memory, the OC4J process will shut down. This will happen if references to the objects are not released. For example, if objects are stored in a hash table or vector and never again removed.
It is of course possible that your process actually needs to use a lot of memory. In this case, the maximum heap size for the process should be increased to avoid frequent garbage collection.
To maximize performance, set the maximum heap size to accommodate application requirements. To determine how much Java heap you need, include calls in your program to the Runtime.getRuntime().totalMemory()
and Runtime.getRuntime().freeMemory
methods in the java.lang
package. Subtract free memory from total memory; the difference is the amount of heap that the application consumed.
Depending on the particular J2EE application, setting the command line option -server
for the JVM running OC4J may improve performance (the JVM runs in one of two modes set with the two related options, -client
and -server
, the default value is -client
). To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -server
Java option.
The -server
option selects the server VM instead of using the default client VM. The client and the server VMs are similar, except that the server VM is specially tuned to maximize peak operating speed. It is intended for executing long-running server applications, for which having the fastest possible operating speed is generally more important than having a fast startup time or a smaller runtime memory footprint. The client VM, the default without using the -server
option starts up faster and requires a smaller memory footprint than the server VM.
Depending on the particular J2EE application, changing the setting of the command line option -Xss
for the JVM running OC4J may improve performance. To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -Xss
Java option.
This option sets the maximum stack size for C code in a thread to n. Every thread that is spawned during the execution of the program passed to java has n as its C code stack size. The default C code stack size is 512 kilobytes (-Xss512k
). A value of 64 kilobytes is the smallest amount of C code stack space allowed per thread.
Oracle recommends that you try the following value to improve the performance of your J2EE applications:
-Xss128k
Depending on the particular J2EE application and JDK version, changing the setting of the command line option -Xconcurrentio
for the JVM running OC4J may improve performance. To set this option, use the procedures outlined in "Using Oracle Enterprise Manager to Change OC4J JVM Command Line Options", and specify the -Xconcurrentio
Java option.
This option generally helps programs with many threads. The main feature turned on with -Xconcurrentio
is to use LWP based synchronization instead of thread based synchronization. For certain applications, with JDK 1.3.1, this option increases speed up by over 40%. See the following site for more information,
http://java.sun.com/docs/hotspot/threads/threads.html
Using the -Xconcurrentio
option, it is important to compare results for your application without the option. In some tests, results have been mixed, using the option results in a speedup for some applications, but for other applications or JDK versions, the performance degraded with this option. See the following site,
http://java.sun.com/docs/hotspot/PerformanceFAQ.html
To change the Java command line options for an OC4J Instance, go to the home page for the OC4J Instance and perform the following steps:
For example, enter the following to set the JVM heap sizes to 128 Megabytes:
-Xmx128m
Figure 6-1 shows the Server Properties page with Java Options.
A data source, which is the instantiation of an object that implements the javax.sql.DataSource
interface, enables you to retrieve a connection to a database server. This section describes data source configuration options for global data sources. A global data source is available to all the deployed applications in an OC4J Instance.
This section covers the following topics:
See Also:
Some of the performance related configuration options have different affects, depending on the type of the data source. OC4J supports two types of data sources, emulated and non-emulated:
The pre-installed default data source is an emulated data source. Emulated data sources are wrappers around Oracle data sources. If you use these data sources, your connections are extremely fast, because they do not provide full XA or JTA global transactional support. We recommend that you use these data sources for local transactions or when your application requires access or update to a single database. You can use emulated data sources for Oracle or non-Oracle databases.
You can use the emulated data source to obtain connections to different databases by changing the values of the url
and connection-driver
parameters.
The following is a definition of an emulated data source:
<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. These are used by applications that want to coordinate access to multiple sessions within the same database or to multiple databases within a global transaction.
Each data source is configured with one or more logical names that allow you to identify the data source within J2EE applications. The ejb-location
is the logical name of an EJB data source. In addition, use the ejb-location
name to identify data sources for most J2EE applications, where possible, even when not using EJBs. The ejb-location
only applies to emulated data sources. You can use this option for single phase commit transactions or emulated data sources.
Using the ejb-location
, the data source manages opening a pool of connections, and manages the pool. Opening a connection to a database is a time-consuming process that can sometimes take longer than the operation of getting the data itself. Connection pooling allows client requests to have faster response times, because the applications do not need to wait for database connections to be created. Instead, the applications can reuse connections that are available in the connection pool.
The max-connections
option specifies the maximum number of open connections for a pooled data source. To improve system performance, the value you specify for the number max-connections
depends on a combination of factors including the size and configuration of your database server, and the type of SQL operations that your application performs.
The default value for max-connections
and the handling of the maximum depends on the data source type, emulated or non-emulated.
For emulated data sources, there is no default value for max-connections
, but the database configuration limits that affect the number of connections apply. When the maximum number of connections, as specified with max-connections
, are all active, new requests must wait for a connection to be become available. The maximum time to wait is specified with wait-timeout
.
For non-emulated data sources, there is a property, cacheScheme
, that determines how max-connections is interpreted. Table 6-2 lists the values for the cacheScheme
property (DYNAMIC_SCHEME
is the default value for cacheScheme
).
See Also:
|
The tradeoffs for changing the value of max-connections
are:
max-connections
.
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.
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
.
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:
wait-timeout
.
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.
Figure 6-2 shows the Oracle Enterprise Manager configuration page that lets you view or modify a data source. This page is available in Oracle Enterprise Manager by selecting the Edit button for a selected data source from the Data Sources page from the application default page for an OC4J Instance, or by selecting data sources from the administration section of a deployed application's description page (this is only available when the application has its own local data source).
Oracle Enterprise Manager stores the data sources elements that you add or modify in an XML file. This file defaults to the name data-sources.xml
and is located in /j2ee/home/config
. If you want to change the name or the location of this file, you can do this in the General Properties page off of the default application screen or off of your specific application's page, when the application specifies a local data source.
Text description of the illustration em_datasourceconfig.gif
This section discusses configuration options and performance tips specific to servlets for optimizing OC4J performance.
This section covers the following topics:
This section cover the following:
By default, OC4J loads a servlet when the first request is made. OC4J also allows you to load servlet classes when the JVM that runs the servlet is started. To do this, add the <load-on-startup>
sub-element to the <servlet>
element in the application's web.xml
configuration file.
For example, add the <load-on-startup>
as follows:
<servlet> <servlet-name>viewsrc</servlet-name> <servlet-class>ViewSrc</servlet-class> <load-on-startup> </servlet>
Using the load-on-startup facility increases the start-up time for your OC4J process, but decreases first-request latency for servlets.
Using Oracle Enterprise Manager you can also specify that OC4J load for an entire Web Module on startup. To specify that a web module is to be loaded on startup, select the Website Properties page for an OC4J Instance and then use the Load on Startup checkbox.
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 Oracle Enterprise Manager, 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.time
and sessionActivation.completed
and sessionActivation.active
.
This example shows an application that creates sessions, but never uses them:
To provide an example, we show metrics from a JSP under /oc4j/
application
/WEBs/
context
:
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 it causes memory or CPU consumption problems.
A well-tuned application shows sessionActivation.active
with a value that is less than sessionActivation.completed
before the session time out. This indicates that the sessions are probably being used and cleaned up.
Suppose we have a servlet that uses sessions effectively and invalidates them appropriately. Then we might see a set of metrics such as the following, under /oc4j/<application>/WEBs/<context>
:
session.Activation.active: 2 ops session.Activation.completed: 500 ops
The fact that two sessions are active when more than 500 have been created and completed indicates that sessions are being invalidated after use.
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:
Oracle9iAS provides JSP tag libraries that include some features that may improve the performance of J2EE applications. For example, you may be able to use the JSP caching features available in the tag libraries to increase the speed and scalability for your applications:
This section describes JSP configuration parameters that you can alter to improve and control JSP operation. These parameters are set for each OC4J Instance, by altering the file global-web-application.xml
.
See Also:
|
The main_mode
parameter determines whether classes are automatically reloaded or JSPs are automatically recompiled, in case of changes.
Table 6-3 shows the supported settings for main_mode
.
Note the following when working with the main_mode
parameter:
<%@ include ... %>
syntax as opposed to <jsp:include ... />
syntax, are included during translation-time.
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 session objects created. You can turn off sessions for your JSPs if you do not want a new session created for each request. By default, in OracleJSP sessions are enabled. If you do not need to use sessions in your JSPs, turn them off by including the following line at the top of the JSP:
<%@ page session="false" %>
If you use sessions, ensure that you explicitly cancel the session. If you do not cancel a session, it remains active until it times out. Invoke the invalidate()
method to cancel a session.
The default session timeout for OC4J is 30 minutes. You can change this for a specific application by setting the <session-timeout>
parameter in the <session-config>
element of web.xml
.
For example, the following code shows how you would cancel a session after you have finished using it:
HtttpSession session; session = httpRequest.getSession(true); . . . 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.
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.
<% 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(); %>
<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:
status checker
page from each page of your application.
Oracle9iAS Containers for J2EE Support for JavaServer Pages Reference in the Oracle9i Application Server documentation library
See Also:
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:
include
command (jsp:include
) to include its output in the JSP output at runtime.
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.
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:
This section covers parameters that you can tune for EJB performance in the server.xml
file for an OC4J Instance.
You can change the default value for the transaction configuration timeout in the transaction-config
element in the server.xml
file for the OC4J Instance. The transaction-confi
g timeout is not an EJB specific timeout, but affects all transactions which use EJBs. This configuration parameter specifies the maximum time taken for a transaction to finish before it can get rolled back due to a timeout. This parameter applies to all transactions on the OC4J Instance. The default value for this parameter is 60000 milliseconds (60 seconds).
For example, the following server.xml
sets the transaction-config
timeout parameter to 30 seconds:
<transaction-config timeout="30000"/>
Increase this value if your applications that use transactions are getting transaction timeout errors, or if your transactions may be longer than 60 seconds (including waiting for connections set by wait-timeout
in datasources.xml
).
The transaction-config
timeout applies for all transactions running in OC4J, and therefore must be big enough for your longest transaction. If you specify a small timeout value for transaction-config
timeout, then you cannot set the timeout to a larger value for an individual EJB, since the transaction-config
timeout
applies for all transactions at the EJB level. Thus, the timeout should be set to a value greater than or equal to the timeouts used within a transaction (for example the data sources wait-timeout
, and the EJB call-timeout
).
This section covers parameters that you can tune for EJB performance that are specific to OC4J. These parameters are set in the orion-ejb-jar.xml
file.
This section covers the following topics:
Table 6-4 lists parameters that you can tune for EJB performance that are specific to OC4J. These parameters apply for all types of EJBs, including session and entity beans. The parameters in Table 6-4 are specified in orion-ejb-jar.xml
.
Parameter | Description |
---|---|
|
Applies for session and entity beans. This parameter specifies the maximum time to wait for any resource that the EJB container needs, excluding database connections, before the container calls the EJB method. Default Values: 90000 milliseconds for entity beans and 0 (forever) for session beans. |
|
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: 3 (for session beans and entity beans) See Also: "Setting the Transaction Configuration Timeout" See Also: "Setting the Connection Retry Interval in Data Sources" |
This section covers parameters for entity beans using CMP. These parameters are specified in the orion-ejb-jar.xml
configuration file that affect performance.
Table 6-5 lists the entity bean CMP specific parameters.
Table 6-6 describes the supported locking-mode
parameter values.
Parameter | Description |
---|---|
|
For a description, see Table 6-4 |
|
Recommend setting to Default Value: true |
|
Default is false for beans with
This parameter corresponds to which commit option is used (A, B or C, as defined in the EJB specification). When
The |
|
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-7 for a description of Default value: |
|
The locking modes, specified with the
See Table 6-6 for a description of
See Table 6-7 for a description of |
|
For a description, see Table 6-4 |
|
Specifies whether the container updates only modified fields or all fields to persistence storage for CMP entity beans when ejbStore is invoked.
Default Value: |
|
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 |
The locking-mode
, along with isolation
, assures database consistency for EJB entity beans using CMP. Table 6-7 shows the common locking-mode
and isolation
combinations. The different combinations have both functional and performance implications, but often the functional requirements for data consistency will lead to selecting a mode, even when it may be at the expense of performance.
In Table 6-7 the isolation
setting refers to either the transaction isolation
attribute setting, if explicitly set, or to the database isolation level (if the transaction isolation
attribute is not set). Also, although locking-mode
and transaction isolation levels are set as attributes of a CMP bean, the isolation level that will be in effect for the transaction is the isolation level of the first entity bean used in the transaction. Therefore it is best to set all beans in the same transaction to the same isolation level.
In general, optimistic locking with committed isolation will be faster since it allows for more concurrency, but it may not meet your needs for data consistency. Pessimistic locking with committed isolation, and optimistic locking with serializable isolation will be slower, but will guarantee data consistency on updates.
Defining a bean as read-only will assure that no updates are allowed to the bean. The performance will be similar to a bean which may not be defined as read-only, and yet is never used to do inserts, updates, or deletes (i.e. only the methods which read are called). This is because if no fields are modified in a bean that is not defined with read-only locking, it is already optimized to not do an ejbStore. To see a performance advantage and avoid doing ejbLoads for read-only beans, you must also set exclusive-write-access=true
.
This section covers parameters that apply to entity beans using BMP. These parameters are specified in the orion-ejb-jar.xml
configuration file.
Table 6-8 lists the entity bean BMP specific parameters.
Parameter | Description |
---|---|
|
For a description, see Table 6-4 |
|
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: |
|
For a description, see Table 6-4 |
This section covers the parameters that are specified in the orion-ejb-jar.xml
configuration file and apply for session beans.
Table 6-9 lists the stateless session bean specific parameters.
Table 6-10 lists the stateful session bean specific parameters.
Parameter | Description |
---|---|
|
For a description, see Table 6-4 |
|
The
For stateless session beans, if you specify a Default Value: 60 (seconds) |
|
For a description, see Table 6-4 |
Parameter | Description |
---|---|
|
For a description, see Table 6-4 |
|
The
The timeout parameter is an inactivity timeout for stateful session beans. Every 30 seconds the pool clean up logic is invoked. Within the pool clean up logic, only the sessions that timed out, by passing the
Adjust the If your application requires that a stateful session bean be available for longer than 30 minutes, then adjust the timeout value accordingly. Default Value: 30 (minutes) |
|
For a description, see Table 6-4 |
This section describes techniques that allow you to improve performance by setting the number of active processes within an OC4J Instance, sending applications to different OC4J Instances, and limiting the number of requests sent to an OC4J Instance.
This section covers the following topics:
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
.
If you are using standalone OC4J you can limit the number of active web users an OC4J site accepts concurrently by constraining the maximum allowable HTTP connections. Tuning parameters on a standalone OC4J can improve performance if there are a large number of concurrent users that the system cannot efficiently handle, or when there are limited resources which you cannot easily constrain.
To limit the HTTP connections, use the max-http-connections
configuration element in server.xml
and specify the attributes: value
, max-connections-queue-timeout
, and socket-backlog
attributes.
For example, the following shows a line of server.xml that configures the maximum number of connections:
<max-http-connections max-connections-queue-timeout="120" socket-backlog="50" value="100"/>
Table 6-11 describes the max-http-connections
attributes.
When you want messages to be redirected to a different URL when the maximum connections limit is reached, include the HTTP redirect URL.
For example, to redirect to http://
optional.redirect.url/page.jsp, add the following line to server.xml
:
<max-http-connections max-connections-queue-timeout="120" socket-backlog="50" value="100">http://optional.redirect.url/page.jsp</max-http-connections>
See Also:
Appendix B, "Additional Information" in the Oracle9iAS Containers for J2EE User's Guide for information on the elements in OC4J |
Oracle9iAS lets you configure multiple OC4J processes in an OC4J Instance. If there are sufficient resources on your system, you may be able to improve performance by configuring multiple OC4J processes for the OC4J Instance that services your J2EE application. Using multiple OC4J processes is the simplest form of load balancing without using Oracle9iAS clustering. Configuring an OC4J Instance to allow requests to be served by multiple OC4J processes can reduce or avoid contention and improve scalability. Oracle9iAS also supports multi node clustering for load balancing.
The optimal ratio of OC4J processes to CPUs is dependent on characteristics of the application, hardware configuration and JDK being used. But in general, for multi-cpu configurations with greater than two processors, you should consider configuring multiple OC4J processes. For example, on a recent test of a J2EE application, a single OC4J process was sufficient to use 70% of the resources on a four processor system. That statistic indicated that either adding a second OC4J process would be advantageous or that the incoming load was insufficient to utilize more of the machine resources. By monitoring the incoming load, we were able to determine that it was the former, and adding a second process improved performance.
Adding processes beyond the available resources of the system will not improve performance. For example, if one OC4J process is sufficient to saturate the CPU resources of a system, adding four more processes is not likely to improve performance and may, in fact, degrade it. A good starting point is to configure one OC4J process for every 2-3 CPUs and measure the improvement derived from adding additional processes.
Using Oracle Enterprise Manager you can specify the number of processes in an OC4J Instance using the OC4J Instance level configuration available on the OC4J Instance's home page.
If you configure your OC4J to use load-balancing with multiple OC4J processes running within the same island, and you do not want sessions to be replicated, make sure that the <distributable/>
property is not set in the application's web.xml
file.
It is often beneficial to spread J2EE application load among multiple OC4J Instances, especially when applications are run on a multiprocessor system. Running multiple OC4J Instances generally results in higher throughput and shorter response time, even on a single-processor host.
If your web site has many different applications deployed which have different requirements and needs, you may want to configure different OC4J Instances, each with the appropriate number of OC4J processes to service the different applications.
To deploy applications to different OC4J Instances, perform the following steps:
After deploying the applications to different OC4J Instances, you can monitor the performance to see if throughput increases, or the response time decreases.
To achieve optimal performance in Oracle9iAS OC4J J2EE applications that use the database, the database tables you access need to be designed with performance in mind, and you need to monitor and tune the database server to assure that the system is performant.
This section contains tips for improving the maintainability, scalability, and performance of your Oracle Business Components for Java (BC4J) 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 BC4J framework makes it easy to switch between them. You can test your application in both modes to see which gives you the best performance.
A client can use application module instances from a pool, called application module pooling. This offers these advantages:
For example, in the case of a web application, you may have 1,000 users but you know that only 100 will be using a certain application module at one time. So you use an application module pool. When a client needs an application module instance, it takes a free one from the pool and releases it to the pool after either committing or rolling back the transaction. Because the instance is precreated, end users are saved the time it takes to instantiate the application module when they want to perform a task. Typically, web-based JSP clients use pools. If you want to make sure that the application module pool has a maximum of 100 application module instances, you can customize the default application module pool.
If your client needs to keep track of application module state, we recommend using stateful mode. In a stateful JSP application, the client does not reserve the application module instance, making it available to other clients if the number of application modules exceeds the recycle threshold. State is, instead, preserved in one of two ways: The application module pool returns a client's original application module if the application module has not been recycled, and the pool persists the state of recycled application modules in the database to be available to clients that request them later.
When you release an application module at the end of a user's session, be sure to use stateless (rather than stateful or reserved) release mode. This frees up database space and allows the pool to recycle the application module immediately.
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 crash, for example), the client will be able to instantiate a new application module with the same state as the lost one, and no work will be lost.
However, some applications do not require this high level of reliability. If you're not worried about loss of work due to server problems, you may want to disable failover. When failover is disabled, the application module's state exists only in memory until it is committed to the database (at which point the application module's state is discarded) or recycled (at which point the state is saved so that the client can retrieve it). By not saving the application module state every time the application module is checked in, failover-disabled mode can improve performance.
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.
There are only two reasons to use JDBC-style bind parameters:
WHERE
clause.
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.
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|