Skip Headers
Oracle® Application Server Forms Services Deployment Guide
10g Release 2 (10.1.2)
B14032-03
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

A.6 Resolving Memory Problems

This section contains the following:

A.6.1 How Java Uses Memory

Like all software programs, a Java applet uses memory. For Java, the language specification requires a 'garbage collector', which is in an internal memory manager for the Java Virtual Machine (JVM). When a Java program needs memory, it requests this memory from the JVM. If there is no memory left, then the JVM will attempt to free some memory by using the garbage collector. The garbage collector will try to release memory that is no longer required to run the program back to the JVM. If there is still insufficient memory to perform the required task then the JVM will attempt to get more memory from the operating system. If that memory allocation fails, then the Java program will be unable to continue.

A.6.2 Setting the Initial Java Heap

You can specify the initial Java Heap (the memory used by the JVM) for your application through Enterprise Manager or at the command line in the middle tier. For example, the following command will set the initial 'Java Heap' (the memory used by the JVM) to 20MB, and the maximum memory to be used by the JVM to 32MB:

appletviewer -J-ms20m -J-mx32Mb dve.html

The default initial and maximum sizes for Appletviewer are 16MB and 20MB respectively.

When using JInitiator, you will need to set the runtime options in the JInitiator control panel.


Note:

The JVM will only use the memory it is told it is allowed to use. Even if you have memory available with the operating system, the JVM will not use it.

A.6.3 About Memory Leaks

A memory leak is an error in a program's dynamic-store allocation logic that causes it to fail to reclaim discarded memory, leading to eventual collapse due to memory exhaustion.

For example, when a program runs it may need to allocate some memory to perform a particular task. If the program has finished with that memory and no longer has any use for it, but fails to make that memory available to other programs running on the computer, then it is said to have leaked the memory.

A typical method used to spot memory leaks is to repeat a series of steps, and observe the memory in use by the application - if the memory usage continues to rise with each iteration, then the assumption is often that the program has a memory leak.

However, some complex applications may choose to retain control of memory it has previously allocated so that it can reuse it at a later point - memory allocation can be an expensive operation, and if the program expects that it will need more memory later it may be more efficient to keep the unused memory available for reuse.

A.6.3.1 Memory Leaks in Java

The Java language specification demands that the JVM has a Garbage Collector (GC). In Java, the programmer allocates memory by creating a new object. There is no way to de-allocate that memory. Periodically the Garbage Collector sweeps through the memory allocated to the program, and determines which objects it can safely destroy, therefore releasing the memory. To determine which objects it can safely destroy, the Garbage Collector uses a 'mark and sweep' algorithm. The Garbage Collector scans the dynamically allocated memory for objects, marking those which still have active references to them.

After all possible paths to objects have been investigated, unmarked objects that are known to be no longer needed can be garbage collected. A common myth with Java programming is that the presence of a Garbage Collector means that there can be no memory leaks. This is not true. The Garbage Collector simply marks those objects, which have active references, and destroys those that do not. It is possible to have an active reference to an object that is no longer needed. This is a memory leak in Java. The solution to the leak is to destroy the references to the object once it is no longer needed so that the Garbage Collector can identify it as safe to destroy. If a memory leak exists in a Java program, then calling the Garbage Collector more frequently will not help.

To complicate matters further, the JVM may choose not to release unused memory back to the operating system. In the real world this seldom matters, as most programs will typically require more memory at some point in the near future and can reuse the free memory in the JVM. However, it is worth bearing in mind that not all the memory allocated to the JVM will be in use by the program running in the JVM.

A.6.3.2 Identifying Memory Leaks

Typically, if a growth in memory usage is observed each time a particular series of operations is performed, then it is a memory leak. The ideal proof is to:

  1. Get the form into an initial base state, and record the memory usage,

  2. Perform a series of steps to illustrate the problem,

  3. Return to the initial base state, and record the memory usage.

By repeating steps 2 and 3, it is possible to determine whether there is a steady memory leak or not. If the growth in memory is small over a large number of iterations, then it may not be a leak at all; it could be that the JVM is retaining unused memory, or the Garbage Collector is not activating as frequently as expected.

A.6.4 Improving Performance with Caching

When any Java program runs, the Java Virtual Machine needs to load class files. When running over the Internet, the time taken to download a class file each time the program runs can lead to performance problems. In order to solve this download problem, the JDK supports Java Archive (Jar) files. A Jar file is simply a collection of class files bundled into one compressed file. Typically, the size of the Jar file will be much smaller than the combined size of the class files it contains.

In addition to reducing the amount of data to be transferred, Jar files also allow JInitiator and Oracle's JDK to use a process referred to as caching. Starting with OJDK 1.1.7.15, several performance improvements were made to the caching process.

When the JVM first references a class, it checks the local computer to see if any of the previously cached Jar files contain this class. If the class does exist in one of the pre-cached Jar files, then the JVM checks to see if there is a newer version of this Jar file on the application server. If there is a newer Jar file available then the new copy of the Jar file is downloaded to the client cache. If the cached Jar file is up to date, then the class file is loaded from the cached Jar file rather than from over the network.

Caching is important because if the application Jar files do not change, then after the application has run once, and all the Jar files required have been cached on the client, then subsequent invocations of the application will always load the classes from the local cached copies. This can lead to significant performance improvements in the startup time for the application. If new classes are needed to run a specific part of the application, these will be downloaded as required.

A.6.5 Performance Improvements in OJDK

While caching means that the Jar file will not be downloaded from the server every time the application is invoked, there were still some issues affecting performance. Since the Jar files contain compressed data, the time to decompress this data from the cached Jar file outweighs the time saved in downloading less data from the network.

Jar files can be digitally signed and undergo authentication to ensure they have not been modified in transit over the network. This procedure involves expensive mathematical calculations. The new caching mechanism introduced in OJDK addresses these issues in the following way:

When the Jar file is downloaded for the first time, two files are created:

  • A data file, which contains all of the unzipped data from the Jar file. Data files have the extension .dxx, where xx is a number between 00 and 99. For example 10f756b8.d00.

  • An index file which contains information about the Jar file, including the URL it was loaded from, the date it was last modified on the server, and a table of contents. The table of contents lists all of the entries in the Jar file, their offsets in the data file, and the authentication status of each entry. Index files have the extension .ixx, where xx is a number between 00 and 99. For example 10f756b8.i00.

The information in these files is stored in a binary format. There is no easy way to read them by eye, and there is little value in doing so.

The first eight characters of all cache files represent the URL where the Jar file was downloaded from. This allows the caching mechanism to quickly find a URL in the cache by mapping the URL to its corresponding eight-character representation and looking for files with that name.

When a class file is required by the application, OJDK uses the information in the table of contents to locate the class file in the data cache. If the data was digitally signed, then the list of authenticated signers is read from the data file.