9 Oracle Database Java Application Performance

You can enhance the performance of your Java application using the following:

Natively Compiled Code

The Java language was designed for a platform-independent and secure development model. To accomplish these goals, some execution performance was sacrificed. Translating Java bytecodes into machine instructions degrades performance. To regain some of the performance loss, you can natively compile certain classes. For example, you can natively compile code with CPU-intensive classes.

Without native compilation, the Java code you load to the server is interpreted and the underlying core classes upon which your code relies, such as java.lang.*, are natively compiled.

Native compilation provides a speed increase ranging from two to ten times the speed of the bytecode interpretation. The exact speed increase is dependent on several factors, including:

  • Use of numerics

  • Degree of polymorphic message sends

  • Use of direct field access, as opposed to accessor methods

  • Amount of array accessing

  • Casts

Because Java bytecodes were designed to be compact, natively compiled code can be considerably larger than the original bytecode. However, because the native code is stored in a shared library, it is shared among all users of the database.

Most Java virtual machines (JVMs) use Just-In-Time (JIT) compilers that convert Java bytecodes to native machine instructions when methods are called. Accelerators use an Ahead-Of-Time approach for recompiling the Java classes. The following table briefly describes the native compilers:

Native Compiler Description
Just-In-Time Provides JVM the ability to translate Java instructions just before they are needed by the application. The benefits depend on how accurately the native compiler anticipates code branches and the next instruction. If incorrect, then no performance gain is realized.
Ahead-Of-Time An accelerator natively compiles all Java code within a Java Archive (JAR) file to native shared libraries organized by a Java package, before run time. At run time, accelerator checks if a Java package has been natively compiled. If so, then the accelerator uses the machine code library instead of interpreting the deployed Java code.

This static compilation approach provides a large, consistent performance gain, regardless of the number of users or the code paths traversed on the server. After compilation, the loadjava utility can be used to load the statically compiled libraries into Oracle Database, which are then shared between users, processes, and sessions.

This sections covers the following topics:

Accelerator Overview

Most Ahead-Of-Time native compilers compile the bytecode directly into a platform-dependent language. For portability requirements, this is not feasible. Figure 9-1 illustrates how an accelerator translates the Java classes into a version of C that is platform-independent. The C code is compiled and linked to supply the final platform-dependent, natively compiled, shared libraries or dynamic-link libraries (DLLs).

Figure 9-1 Native Compilation Using Accelerator

Native compilation using accelerator
Description of "Figure 9-1 Native Compilation Using Accelerator"

Given a JAR file, an accelerator performs the following:

  1. Verifies the classes that are loaded in the database.

  2. Retrieves the Java bytecodes for these classes from the database and stores them in a project directory where the accelerator was called.

  3. Translates the Java bytecodes to C code.

  4. Compiles and links the C code using the C compiler for your platform.

    The accelerator translates, compiles, and links the retrieved classes on the client. For this reason, you must natively compile the code on the intended platform environment in which this application will be deployed. The result is a single deployment JAR file for all classes within the project.

  5. The resulting shared library is loaded into the $ORACLE_HOME/javavm/admin directory.

Note:

The libraries, which are natively compiled by the accelerator, can be used only within Oracle Database. In addition, these libraries can be used only within the same version of Oracle Database in which it was produced. If you want your application to be natively compiled on subsequent releases, then you must recompile these classes. That is, native recompilation of existing libraries will not be performed automatically by any upgrade process.

Oracle Database Core Java Class Libraries

All core Java class libraries and Oracle-provided Java code within Oracle Database are natively compiled for greater execution speed. Java classes exist as shared libraries in $ORACLE_HOME/javavm/admin, where each shared library corresponds to a Java package. For example, orajox10java_lang.so on Sun Solaris and orajox10java_lang.dll on Microsoft Windows hold java.lang classes. Specifics of packaging and naming can vary from platform to platform. The Oracle JVM uses natively compiled Java files internally and opens them, as necessary, at run time.

Natively Compiling Java Application Class Libraries

The command-line tool, ncomp, is an accelerator that natively compiles your code and loads it in Oracle Database. However, to use ncomp, you must first satisfy the installation requirements.

You must perform the following before calling the accelerator:

  1. Install a C compiler for the intended platform on the computer where you are running ncomp.

  2. Verify that the correct compiler and linker commands are referenced within the System*.properties file located in the $ORACLE_HOME/javavm/jahome directory. Because the compiler and linker information is platform-specific, the configuration for these items is detailed in the README for your platform.

  3. Set the JAVA_HOME environment variable to the location where your Java Development Kit (JDK) is installed.

  4. Grant the user that runs ncomp the following role and security permissions:

    1. JAVA_DEPLOY

      The user must be assigned the JAVA_DEPLOY role to be able to deploy the shared libraries on the server, which can be performed using the ncomp and deploync utilities. For example, this role can be assigned to the user DAVE, as follows:

      SQL> GRANT JAVA_DEPLOY TO DAVE;
      
      
    2. FilePermission

      The accelerator stores the shared libraries with the natively compiled code on the server. To enable the accelerator to store these libraries, the user must be granted FilePermission for read and write access to directories and files under $ORACLE_HOME on the server. One method of granting FilePermission for all desired directories is to grant the user the JAVASYSPRIV role, as follows:

      SQL> GRANT JAVASYSPRIV TO DAVE;
      
      

      You must run the following grant by a party that has the permission to run this grant, given that $ORACLE_HOME is equivalent to /private/oracle on the server:

      call dbms_java.grant_permission(<user>, 'java.io.FilePermission', '/private/oracle/-', 'read,write');
      
      

      The following example demonstrates Larry giving Dave FilePermission for $ORACLE_HOME, where $ORACLE_HOME is located in /private/oracle. You cannot provide an environment variable to the grant_permission() method. Once completed, Dave can run ncomp.

      connect larry/larry
      
      REM Grant DAVE permission to read and write the ncomp file.
      call dbms_java.grant_permission('DAVE', 'java.io.FilePermission', '/private/oracle/-','read,write');
      
      REM commit the changes to the PolicyTable
      commit;
      
      

    Note:

    DBA role contains both the JAVA_DEPLOY role and FilePermission for all files under $ORACLE_HOME.

Running the Accelerator

All the Java classes contained within a JAR file must already be loaded within the database. Run the ncomp tool to instruct the accelerator to natively compile all these classes. The following code natively compiles all classes within the pubProject.jar file:

ncomp -user scott/tiger pubProject.jar

Note:

Because native compilation must compile and link all your Java classes, this process may run for few hours. The time involved in natively compiling your code depends on the number of classes to compile and the type of hardware on your computer.

If you change any of the classes within this JAR file, then the accelerator recompiles the shared library for the package that contains the changed classes. It will not recompile all shared libraries. However, if you want all classes within a JAR file to be recompiled, regardless of whether they were natively compiled previously, then run the ncomp with the -force option, as follows:

ncomp -user scott/tiger -force pubProject.JAR

The ncomp Tool

The accelerator, implemented within the ncomp tool, natively compiles all classes within the specified JAR or ZIP file or the list of classes. It natively compiles these classes and places them into shared libraries according to their package. Note that these classes must first be loaded into the database.

If the classes are designated within a JAR file and have already been loaded in the database, then you can natively compile your Java classes, as follows:

ncomp -user SCOTT/TIGER myClasses.jar

There are options that let you control the details of native compilation.

Syntax

ncomp [ options ] class_designation_file
  -user | -u username/password [@database_url]
  [-load]
  [-projectDir | -d project_directory]
  [-force]
  [-lightweightDeployment]
  [-noDeploy]
  [-outputJarFile | -o jar_filename]
  [-thin]
  [-oci | -oci8]
  [-update]
  [-verbose]

Argument Summary

Table 9-1 summarizes the ncomp arguments. class_designation_file can be a file.jar, file.zip, or file.classes file.

Table 9-1 ncomp Argument Summary

Argument Description and Values

file.jar

The full path name and file name of a JAR file that contains the classes that are to be natively compiled. If you are running ncomp in the directory where the JAR file exists and you do not specify the -projectDir option, then you may give only the name of the JAR file.

file.zip

The full path name and file name of a ZIP file that contains the classes that are to be natively compiled. If you are running ncomp in the directory where the ZIP file exists and you do not specify the -projectDir option, then you may give only the name of the ZIP file.

file.classes

The full path name and file name of a classes file, which contains the list of classes to be natively compiled. If you are running ncomp in the directory where the classes file exists and you do not specify the -projectDir option, then you may give only the name of the classes file.

-user | -u username/password [@database_url]

Specifies a user, password, and database connect string. The files will be loaded into this database instance. If you specify the database URL on this option, then you must specify it with Oracle Call Interface (OCI) syntax. To provide a JDBC Thin database URL, use the -thin option.

-force

The native compilation is performed on all classes. Previously compiled classes are not passed over.

-lightweightDeployment

Provides an option for deploying shared libraries and native compilation information separately. This is useful if you need to preserve resources when deploying.

-load

Runs loadjava on the specified class designation file. You cannot use this option in combination with a file.classes file.

-outputJarFile jar_filename

The output of all natively compiled classes is stored in a deployment JAR file. This option specifies the name of the deployment JAR file and its destination directory. If omitted, the ncomp tool names the output deployment JAR file with the same name as the input file with _depl.jar appended as the suffix. If directory is not supplied, then the tool stores the output JAR file into the project directory, which is denoted by -projectDir.

-noDeploy

Specifies that the native compilation results only in the output deployment JAR file, which is not deployed to the server. The resulting deployment JAR can be deployed to any server using the deploync tool.

-thin

The database URL that is provided on the -user option uses a JDBC Thin URL address for the database URL syntax.

-oci | -oci8

The database URL that is provided on the -user option uses an OCI URL address for the database URL syntax. However, if neither -oci nor -thin are specified, then it is assumed that you used an OCI database URL.

-projectDir | -d absolute_path

Specifies the full path for the project directory. If not specified, then the accelerator uses the directory from which ncomp is called as the project directory. This directory must exist. The tool will not create this directory for you. If it does not exist, then the current directory is used.

-update

If you add more classes to class_designation_file that has already been natively compiled, then this flag informs the accelerator to update the deployment JAR file with the new classes. Thus, the accelerator compiles the new classes and adds them to the appropriate shared libraries. The deployment JAR file is updated.

-verbose

Output native compilation text with detail.


Argument Details

Table 9-1 summarizes all the arguments. This section explains the following arguments in detail.

  • user

    {-user | -u} user/password[ @database_url ]
    
    

    The permissible forms of @database_url depend on whether you specify -oci, which is the default, or -thin:

    • -oci:@database_url is optional. If you do not specify, then ncomp uses the user's default database. If specified, then database_url can be a TNS name or an Oracle Net Services name-value list.

    • -thin:@database_url is required. The format is host:lport:SID.

      where:

      • host is the name of the computer running the database.

      • lport is the listener port that has been configured to listen for Oracle Net Services connections. In a default installation, it is 5521.

      • SID is the database instance identifier. In a default installation, it is ORCL.

  • lightweightDeployment

    The accelerator places compilation information and the compiled shared libraries in a single JAR file, copies the shared libraries to $ORACLE_HOME/javavm/admin on the server, and deploys the compilation information to the server. If you want to place the shared libraries on the server yourself, then you can do so using the lightweightDeployment option. This option enables you to perform the deployment in two stages:

    1. Natively compile your JAR file with the -noDeploy and -lightweightDeployment options. This creates an deployment JAR file with only ncomp information, such as transitive closure information. The shared libraries are not saved in the deployment JAR file. As a result, the deployment JAR file is much smaller.

    2. Deploy as follows:

      Copy all output shared libraries from the lib directory of the native compilation project directory to $ORACLE_HOME/javavm/admin on the server.

      Note:

      You need to have FilePermission to write to this directory. FilePermission is included in the DBA and JAVASYSPRIV roles.

      Deploy the lightweight deployment JAR file to the server using deploync.

Errors

Any error that occurs during native compilation is printed to the screen. Errors that occur during deployment of shared libraries to the server or during run time can be viewed with the statusnc tool or by referring to the JACCELERATOR$DLL_ERRORS table.

If an error is caught while natively compiling the designated classes, then the accelerator denotes these errors, abandons work on the current package, and continues its compilation task on the next package. The native compilation continues for the rest of the packages. The package with the class that contained the error will not be natively compiled at all.

After fixing the problem with the class, you can choose to do one of the following:

  • Recompile the shared library

  • Reload the Java class into the database

If you choose to load the correct Java class into the database instead of recompiling the classes, then the corrected class and all classes included in the resolution validation for that class are processed in the interpreted mode. These classes are processed regardless of whether they are located within the same shared library or in a different shared library. This means that the JVM will not run these classes natively. All the other natively compiled classes will continue to run in the native format. When you run the statusnc command on the reloaded class or any of its referred classes, they will have a NEED_NCOMPING status message.

The possible errors for a Java class are:

  • The Java class does not exist in the database. If you do not load the Java class into Oracle Database, then the accelerator does not include the class in the shared library. The class is skipped.

  • The Java class is invalid. That is, one of its references may not be found.

  • For any Java class that is unresolved, the accelerator will try to resolve it before natively compiling. However, if the class cannot be resolved, then it is ignored by the accelerator.

A possible error during deployment of natively compiled JAR file is that the native compilation of your JAR file runs correctly, but the deployment fails. In this case, do not recompile the JAR file, but deploy the natively compiled output JAR file with the deploync command.

Native Compilation Usage Scenarios

The following scenarios demonstrate how each of the ncomp tool options can be used:

Natively Compiling on a Test Platform With Java Classes Already Loaded in the Database

If all classes are loaded into the database and you have completed your testing of the application, then you can use the accelerator to natively compile the tested classes. The accelerator accepts a JAR or ZIP file or a file with a list of classes to determine the packages and classes to be included in the native compilation. It then retrieves all the designated classes from the server and natively compiles them into shared libraries. Each library contains a single package of classes.

Assuming that the classes have already been loaded on the server, you run the following command to natively compile all classes listed within a class designation file, such as the pubProject.jar file, as follows:

ncomp -user SCOTT/TIGER pubProject.jar

If you change any of the classes within the class designation file and ask for recompilation, then the accelerator recompiles only the packages that contain the changed classes. It will not recompile all the packages.

Natively Compiling Java Classes Not Loaded in the Database

Once you have tested the designated classes, you may wish to natively compile them on a host other than the test computer. After you transfer the designated class file to this platform, the classes in this file must be loaded into the database before native compilation can occur. The following command loads the classes through loadjava and then performs native compilation of classes in the class designation file, pubProject.jar:

ncomp -user SCOTT/TIGER@dbhost:5521:orcl -thin -load pubProject.jar

Clean Compile and Generate Output for Future Deployment

If you want all classes within a class designation file to be recompiled, regardless of whether they were previously natively compiled, then run ncomp with the -force option. You may want to use the -force option to ensure that all classes are compiled, resulting in a deployment JAR file that can be deployed to other Oracle Database instances. You can specify the native compilation deployment JAR file with the -outputJarFile option. The following command forces a recompilation of all Java classes in the class designation file, pubProject.jar, and creates a deployment JAR file, pubworks.jar:

ncomp -user SCOTT/TIGER -force -outputJarFile pubworks.jar pubProject.jar

The deployment JAR file contains the shared libraries for your classes, and the installation classes specified to these shared libraries. It does not contain the original Java classes. To deploy the natively compiled deployment JAR file to any Oracle Database instance of the appropriate platform type, you must do the following:

  1. Load the original Java classes into the destination server. For example, the class designation file, pubProject.jar, would be loaded into the database using the loadjava tool.

  2. Deploy the natively compiled deployment JAR file using the deploync tool.

Controlling Native Compilation Build Environment

By default, the accelerator uses the directory where ncomp is run as its build environment. It downloads several class files into this directory and then uses this directory for the compilation and linking process.

If you do not want to the accelerator to store any of its files in the current directory, then create a working directory and specify it as the project directory with the -projectDir option. The following command directs the accelerator to use /tmp/jaccel/pubComped as the build directory.

ncomp -user SCOTT/TIGER -projectDir /tmp/jaccel/pubComped pubProject.jar

Note:

The working directory must exist before specifying it with the -projectDir option. The accelerator will not create this directory for you.

Natively Compiling Specific Classes

You can specify one or more classes, which are to be natively compiled, in a .classes file. You can use the following syntax to specify packages or individual classes or both within this file:

  • Specify classes within one or more packages, as follows:

    import com.myDomain.myPackage.*;
    import com.myDomain.myPackage.mySubPackage.*;
    
    

    Note:

    Java has no formal notion of a subpackage. You must specify each package independently.
  • Specify an individual class, as follows:

    import com.myDomain.myPackage.myClass;
    
    

Once explicitly listed, specify the name and location of this class designation file on the command line.

Consider the following pubworks.classes file:

import com.myDomain.myPackage.*;
import com.myDomain.hisPackage.hisSubPackage.*;
import com.myDomain.herPackage.herClass;
import com.myDomain.petPackage.petClass;

The following command directs the accelerator to compile all the classes designated in the pubworks.classes file:

ncomp -user SCOTT/TIGER /tmp/jaccel/pubComped/pubworks.classes

All the classes in myPackage and hisSubPackage and the individual classes, herClass and myClass, are compiled.

Natively Compiling Packages That Are Fully or Partially Modified

If you change any of the classes within the deployment JAR file, then the accelerator will only recompile shared libraries that contain the changed classes. It will not recompile all shared libraries designated in the JAR file. However, if you want all the classes in a JAR file to be recompiled, regardless of whether they were previously natively compiled, then you must run ncomp with the -force option, as follows:

ncomp -user scott/tiger -force pubProject.JAR

The deploync Tool

You can deploy any deployment JAR file with the deploync command. This includes the default output JAR file, file_depl.jar, or the JAR file created when you use the ncomp -outputJarFile option. The operating system and Oracle Database version must be the same as the platform where it was natively compiled.

Note:

The list of shared libraries deployed into Oracle Database are listed in the JACCELERATOR$DLLS table.

Syntax

deploync [options] deployment.jar
  -user | -u username/password [@database_url]
  [-projectDir | -d project_directory]
  [-thin]
  [-oci | -oci8]

Argument Summary

Table 9-2 summarizes the deploync arguments.

Table 9-2 deploync Argument Summary

Argument Description and Values

deployment.jar

The full path name and file name of a deployment JAR file. This JAR file is created when you specify the -outputJarFile option on the ncomp tool. Note that deploync does not verify that this is a native compilation deployment JAR file.

-user | -u username/password [@database_url]

Specifies a user name, password, and database connect string. The files will be loaded into this database instance. If you specify the database URL on this option, then you must specify it with the OCI syntax. To provide a JDBC Thin database URL, use the -thin option.

-projectDir | -d absolute_path

Specifies the full path for the project directory. If not specified, the accelerator uses the directory from which ncomp is called as the project directory.

-thin

The database URL that is provided on the -user option uses a JDBC Thin URL address for the database URL syntax.

-oci | -oci8

The database URL that is provided on the -user option uses an OCI URL address for the database URL syntax. However, if neither -oci nor -thin are specified, then the OCI database URL is assumed, by default.


Example

Deploy the natively compiled deployment JAR file, pub.jar, to the dbhost database as follows:

deploync -user SCOTT/TIGER@dbhost:5521:orcl -thin /tmp/jaccel/PubComped/pub.jar

The statusnc Tool

After the native compilation is completed, you can check the status of the Java classes using the statusnc command. This tool prints the status of each class either to the screen or to a designated file. In addition, it always saves the output in the JACCELERATOR$STATUS table. The values can be the following:

Native Compilation Class Status Description
ALREADY_NCOMPED The class is currently natively compiled.
NEED_NCOMPING A class within the shared library was reloaded after native compilation. As a result, you should recompile this shared library.
INVALID A class loaded in the database is invalid. The accelerator tried to validate it and failed. The class will be excluded from the natively compiled shared library.

Note:

The JACCELERATOR$STATUS table contains only the output from the last run of the statusnc command. When run, statusnc cleans this table before writing the new records into it.

Syntax

statusnc [ options ] class_designation_file
  -user user/password[@database_url]
  [-output | -o filename]
  [-projectDir | -d directory]
  [-thin]
  [-oci | -oci8]

Argument Summary

Table 9-3 summarizes the statusnc arguments. The class_designation_file can be a .jar, .zip, or .classes file.

Table 9-3 statusnc Argument Summary

Argument Description

file.jar

The full path name and file name of a JAR file that was natively compiled.

file.zip

The full path name and file name of a ZIP file that was natively compiled.

file.classes

The full path name and file name of a classes file, which contains the list of classes that was natively compiled.

-user | -u username/password [@database_url]

Specifies a user name, password, and database connect string where the files are loaded. If you specify the database URL on this option, then you must specify it with OCI syntax. To provide a JDBC Thin database URL, use the -thin option.

-output filename

Designates that statusnc should send the output to the specified text file rather than to the screen.

-projectDir | -d absolute_path

Specifies the full path for the project directory. If not specified, the accelerator uses the directory from which ncomp is called as the project directory.

-thin

The database URL that is provided on the -user option uses a JDBC Thin URL address for the database URL syntax.

-oci | -oci8

The database URL that is provided on the -user option uses an OCI URL address for the database. However, if neither -oci nor -thin are specified, then the default assumes an OCI database URL.


Example

statusnc -user SCOTT/TIGER -output pubStatus.txt /tmp/jaccel/PubComped/pub.jar

Java Memory Usage

The typical and custom database installation process furnishes a database that has been configured for reasonable Java usage during development. However, run-time use of Java should be determined by the usage of system resources for a given deployed application. Resources you use during development can vary widely, depending on your activity. The following sections describe how you can configure memory, how to tell how much System Global Area (SGA) memory you are using, and what errors denote a Java memory issue:

Configuring Memory Initialization Parameters

You can modify the following database initialization parameters to tune your memory usage to reflect your application needs more accurately:

  • SHARED_POOL_SIZE

    Shared pool memory is used by the class loader within the JVM. The class loader, on an average, uses about 8 KB of memory for each loaded class. Shared pool memory is used when loading and resolving classes into the database. It is also used when compiling the source in the database or when using Java resource objects in the database.

    The memory specified in SHARED_POOL_SIZE is consumed transiently when you use loadjava. The database initialization process requires SHARED_POOL_SIZE to be set to 50 MB because it loads the Java binaries for approximately 8,000 classes and resolves them. The SHARED_POOL_SIZE resource is also consumed when you create call specifications and as the system tracks dynamically loaded Java classes at run time.

  • JAVA_POOL_SIZE

    The Oracle JVM memory manager allocates all other Java state during run time from the amount of memory allocated using JAVA_POOL_SIZE. This memory includes the shared in-memory representation of Java method and class definitions, as well as the Java objects migrated to session space at end-of-call. In the first case, you will be sharing the memory cost with all Java users. In the second case, in a shared server, you must adjust JAVA_POOL_SIZE allocation based on the actual amount of state held in static variables for each session.

  • JAVA_SOFT_SESSIONSPACE_LIMIT

    This parameter lets you specify a soft limit on Java memory usage in a session, which will warn you if you must increase your Java memory limits. Every time memory is allocated, the total memory allocated is checked against this limit.

    When a user's session Java state exceeds this size, Oracle JVM generates a warning that is written into the trace files. Although this warning is an informational message and has no impact on your application, you should understand and manage the memory requirements of your deployed classes, especially as they relate to usage of session space.

  • JAVA_MAX_SESSIONSPACE_SIZE

    If a Java program, which can be called by a user, running in the server can be used in a way that is not self-limiting in its memory usage, then this setting may be useful to place a hard limit on the amount of session space made available to it. The default is 4 GB. This limit is purposely set extremely high to be normally invisible.

    When a user's session Java state attempts to exceeds this size, the application can receive an out-of-memory failure.

Initializing Pool Sizes within Database Templates

You can set the defaults for JAVA_POOL_SIZE and SHARED_POOL_SIZE in the database installation template. The Database Configuration Assistant enables you to modify these values in the Memory section, as shown in Figure 9-2.

Figure 9-2 Configuring Oracle JVM Memory Parameters

Configuring Oracle JVM memory parameters
Description of "Figure 9-2 Configuring Oracle JVM Memory Parameters"

Java Pool Memory

Java pool memory is used in server memory for all session-specific Java code and data within the JVM. Java pool memory is used in different ways, depending on what mode the Oracle Database server is running in.

Java Pool Memory Used within a Dedicated Server

The following is what constitutes the Java pool memory used within a dedicated server:

  • The shared part of each Java class used per session.

    This includes read-only memory, such as code vectors, and methods. In total, this can average about 4 KB to 8 KB for each class.

  • None of the per-session Java state of each session.

    For a dedicated server, this is stored in the User Global Area (UGA) within the Program Global Area (PGA), and not within the SGA.

Under dedicated servers, the total required Java pool memory depends on the applications running and may range between 10 and 50 MB.

Java Pool Memory Used within a Shared Server

The following is what constitutes the Java pool memory used within a shared server:

  • The shared part of each Java class that is used per session.

    This includes read-only memory, such as vectors, and methods. In total, this can average about 4 KB to 8 KB for each class.

  • Some of the UGA used for per-session state of each session is allocated from the Java pool memory within the SGA

    Because the Java pool memory size is fixed, you must estimate the total requirement for your applications and multiply by the number of concurrent sessions the applications want to create, to calculate the total amount of necessary Java pool memory. Each UGA grows and shrinks as necessary. However, all UGAs combined must be able to fit within the entire fixed Java pool space.

Under shared servers, this figure could be large. Java-intensive, multiuser benchmarks could require more than 100 MB.

Note:

If you are compiling code on the server, rather than compiling on the client and loading to the server, then you might need a bigger JAVA_POOL_SIZE than the default 20 MB.

Displaying Used Amounts of Java Pool Memory

You can find out how much of Java pool memory is being used by viewing the V$SGASTAT table. Its rows include pool, name, and bytes. Specifically, the last two rows show the amount of Java pool memory used and how much is free. The total of these two items equals the number of bytes that you configured in the database initialization file.

SVRMGR> select * from v$sgastat;

POOL        NAME                            BYTES
----------- -------------------------- ----------
            fixed_sga                       69424
            db_block_buffers              2048000
            log_buffer                     524288
shared pool free memory                  22887532
shared pool miscellaneous                  559420
shared pool character set object            64080
shared pool State objects                   98504
shared pool message pool freequeue         231152
shared pool PL/SQL DIANA                  2275264
shared pool db_files                        72496
shared pool session heap                    59492
shared pool joxlod: init P                   7108
shared pool PLS non-lib hp                   2096
shared pool joxlod: in ehe                4367524
shared pool VIRTUAL CIRCUITS               162576
shared pool joxlod: in phe                2726452
shared pool long op statistics array        44000
shared pool table definiti                    160
shared pool KGK heap                         4372
shared pool table columns                  148336
shared pool db_block_hash_buckets           48792
shared pool dictionary cache              1948756
shared pool fixed allocation callback         320
shared pool SYSTEM PARAMETERS               63392
shared pool joxlod: init s                   7020
shared pool KQLS heap                     1570992
shared pool library cache                 6201988
shared pool trigger inform                  32876
shared pool sql area                      7015432
shared pool sessions                       211200
shared pool KGFF heap                        1320
shared pool joxs heap init                   4248
shared pool PL/SQL MPCODE                  405388
shared pool event statistics per sess      339200
shared pool db_block_buffers               136000
java pool   free memory                  30261248
java pool   memory in use                19742720
37 rows selected.

Correcting Out of Memory Errors

If you run out of memory while loading classes, then it can fail silently, leaving invalid classes in the database. Later, if you try to call or resolve any invalid classes, then a ClassNotFoundException or NoClassDefFoundException instance will be thrown at run time. You would get the same exceptions if you were to load corrupted class files. You should perform the following:

  • Verify that the class was actually included in the set you are loading to the server.

  • Use the loadjava -force option to force the new class being loaded to replace the class already resident in the server.

  • Use the loadjava -resolve option to attempt resolution of a class during the load process. This enables you to catch missing classes at load time, rather than at run time.

  • Double check the status of the newly loaded class by connecting to the database in the schema containing the class, and run the following:

    SELECT * FROM user_objects WHERE object_name = dbms_java.shortname('');
    
    

    The STATUS field should be VALID. If loadjava complains about memory problems or failures, such as lost connection, then increase SHARED_POOL_SIZE and JAVA_POOL_SIZE, and try again.