|Oracle8i Java Developer's Guide
Release 3 (8.1.7)
Part Number A83728-01
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:
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_SIZEallocation based on the actual amount of state held in static variables for each session. See "Java Pool Memory" for more information on
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 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.
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.
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.
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 1974272037 rows selected.
If you run out of memory while compiling (within
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.
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
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:
loadjava -forceoption to force the new class being loaded to replace the class already resident in the server.
loadjava -resolveoption to attempt resolution of a class during the load process. This allows you to catch missing classes at load time, not run time.
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.