Oracle8i Java Developer's Guide Release 3 (8.1.7) Part Number A83728-01 |
Library | Service | Contents | Index

## Java Memory Usage

The typical and custom database installation process furnishes a database that has been configured for reasonable Java usage during development. However, runtime 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 depending on your performance needs, how to tell how much SGA memory you are using, and what errors denote a Java memory issue:

- Configuring Memory Initialization Parameters

- Java Pool Memory

- Displaying Used Amounts of Java Pool Memory

- Correcting Out of Memory Errors

### Configuring Memory Initialization Parameters

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

- `SHARED_POOL_SIZE`--Shared pool memory is used by the class loader within the JVM. The class loader uses an average of about 8 KB for each loaded class. Shared pool memory is used when loading and resolving classes into the database. It is also used when compiling 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 (executing `initjvm.sql` against a clean database, as opposed to the installed seed database) requires `SHARED_POOL_SIZE` to be set to 50 MB as 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 runtime.

- `JAVA_POOL_SIZE`--Aurora's memory manager allocates all other Java state during runtime execution 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, under MTS, you must adjust `JAVA_POOL_SIZE` allocation based on the actual amount of state held in static variables for each session. See "Java Pool Memory" for more information on `JAVA_POOL_SIZE`.

- `JAVA_SOFT_SESSIONSPACE_LIMIT`--This parameter allows you to specify a soft limit on Java memory usage in a session, which will warn you if you must increase your Java memory limits. The memory that you request in this parameter is allocated when the session is started.

  When a user's session-duration Java state exceeds this size, Aurora generates a warning that is written into the trace files. The default is 1 MB. You should understand the memory requirements of your deployed classes, especially as they relate to usage of session space.

- `JAVA_MAX_SESSIONSPACE_SIZE`--If a user-invokable Java program executing in the server can be used in a way that is not self-limiting in its memory usage, 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-duration Java state attempts to exceeds this size, your application can receive an out-of-memory failure.

JServer's unique memory management facilities and sharing of read-only artifacts (such as bytecodes) enables HelloWorld to execute with a per-session incremental memory requirement of only 35 KB. More stateful server applications, such as the Aurora/ORB that CORBA and EJB applications use, have a per-session incremental memory requirement of approximately 200 KB. Such applications must retain a significant amount of state in static variables across multiple calls. Refer to the discussion in the section, "End-of-Call Migration", for more information on understanding and controlling migration of static variables at end-of-call.

### 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 Oracle8i server is running in.

##### Java pool memory used within a dedicated server

The shared part of each Java class used per session. This includes readonly memory, such as code vectors, and methods. In total, this can average about 4-8 KB for each class.

None of the per-session Java state of each session. For a dedicated server, this is stored in UGA within the PGA--not within the SGA.

Under dedicated servers, which is probably the case for applications using only Java Stored Procedures, the total required Java pool memory is not much more than 10 MB.

##### Java pool memory used within a Multi-Threaded Server (MTS)

The shared part of each Java class that is used per session. This includes readonly memory, such as vectors, and methods. In total, this can average about 4-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. Since Java pool memory size is fixed, you must estimate the total requirement for your applications and multiply by the number of concurrent sessions they want to create a 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 MTS servers, which is the case for applications using CORBA or EJB, this figure could be very large. Java-intensive, multi-user benchmarks could require more than 1 GB. Current size limitations are unknown; however, it is platform dependent.

Note: If you are compiling code on the server, rather than compiling on the client and loading to the server, you might need a bigger JAVA_POOL_SIZE than the default 20 MB. EJB deployment uses the Java compiler on the server; therefore, it also requires a larger JAVA_POOL_SIZE.

### 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 what 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

- Running out of memory while compiling

- Running out of memory while loading

#### Running out of memory while compiling

If you run out of memory while compiling (within `loadjava` or `deployejb`), you should see an error:

    A SQL exception occurred while compiling: : ORA-04031: unable to allocate  bytes
    of shared memory ("shared pool","unknown object","joxlod: init h", "JOX: ioc_
    allocate_pal")

The cure is to shut down your database and to reset JAVA_POOL_SIZE to a larger value. The mention of "shared pool" in the error message is a misleading reference to running out of memory in the "Shared Global Area". It does not mean you should increase your SHARED_POOL_SIZE. Instead, you must increase your JAVA_POOL_SIZE, restart your server, and try again.

#### Running out of memory while loading

If you run out of memory while loading classes, it can fail silently, leaving invalid classes in the database. Later, if you try to invoke or resolve any invalid classes, you will see `ClassNotFoundException` or `NoClassDefFoundException` exceptions being thrown at runtime. 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. Many people have accidently forgotten to load just one class out of hundreds and spend considerable time chasing this down.

- 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 allows you to catch missing classes at load time, not run time.

- Double check the status of a newly loaded class by connecting to the database in the schema containing the class, and execute 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 "connection lost", increase SHARED_POOL_SIZE and JAVA_POOL_SIZE, and try again.

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index